Dapatkan konteks proyek uji dalam kasus uji junit Android

108

Apakah ada yang tahu bagaimana Anda bisa mendapatkan konteks proyek Uji dalam kasus uji junit Android (meluas AndroidTestCase).

Catatan: Tes ini BUKAN tes instrumentasi.

Catatan 2: Saya memerlukan konteks proyek uji, bukan konteks aplikasi sebenarnya yang diuji.

Saya memerlukan ini untuk memuat beberapa file dari aset dari proyek pengujian.

peceps
sumber
Mengapa Anda tidak bisa menggunakan InstrumentationTestCase saja?
yorkw
1
Karena saya menguji layanan, bukan UI.
peceps
1
Ada jawaban yang lebih baik ditemukan di sini: [Menggunakan AndroidTestCase alih-alih uji JUnit] [1] [1]: stackoverflow.com/questions/3170706/…
Jaime Botero

Jawaban:

137

Ada pendekatan baru dengan Pustaka Dukungan Pengujian Android (saat ini androidx.test:runner:1.1.1). Contoh update Kotlin:

class ExampleInstrumentedTest {

    lateinit var instrumentationContext: Context

    @Before
    fun setup() {
        instrumentationContext = InstrumentationRegistry.getInstrumentation().context
    }

    @Test
    fun someTest() {
        TODO()
    }
}

Jika Anda juga ingin menjalankan konteks aplikasi:

InstrumentationRegistry.getInstrumentation().targetContext

Contoh berjalan penuh: https://github.com/fada21/AndroidTestContextExample

Lihat di sini: Apa perbedaan antara getTargetContext () dan getContext (di InstrumentationRegistry)?

fada21
sumber
1
Akhirnya jawaban tentang cara menggunakan JUnit4 dengan InstrumentationTest. Setelah berjam-jam mencari. Harus menyukai pengembangan Android.
Fabian Zeindl
1
Bagus! tx (perhatikan ada kesalahan ketik di anggota kelas Anda)
Greg
1
Bisakah seseorang membantu tentang dependensi apa yang perlu ditambahkan di file gradle agar ini berfungsi?
Greg
1
Jangan lupa untuk menambahkan compile "com.android.support.test:runner:1.0.1"ke gradle Anda
egorikem
2
Sudah usang, gunakan InstrumentationRegistry.getInstrumentation().contextsaja.
Allan Veloso
37

Setelah beberapa penelitian, satu-satunya solusi yang berfungsi tampaknya adalah solusi yang sudah ditunjukkan Yorkw. Anda harus memperluas InstrumentationTestCase lalu Anda bisa mengakses konteks aplikasi pengujian Anda menggunakan getInstrumentation (). GetContext () - berikut ini cuplikan kode singkat menggunakan saran di atas:

public class PrintoutPullParserTest extends InstrumentationTestCase {

    public void testParsing() throws Exception {
        PrintoutPullParser parser = new PrintoutPullParser();
        parser.parse(getInstrumentation().getContext().getResources().getXml(R.xml.printer_configuration));
    }
}
AgentKnopf
sumber
7
Ya, tetapi tampaknya konyol bahwa Android tidak menyediakan akses ke konteks proyek pengujian dalam pengujian JUnit sederhana. Konteksnya ada di AndroidTestCase.mTestContext tetapi bersifat pribadi. Saya tidak mengerti kenapa.
peceps
@peceps Full Ack - tapi begitulah adanya dan saya juga tidak menyukainya;)
AgentKnopf
25

Seperti yang Anda baca di kode sumber AndroidTestCase , getTestContext()metode ini disembunyikan.

/**
 * @hide
 */
public Context getTestContext() {
    return mTestContext;
}

Anda dapat melewati @hide anotasi menggunakan refleksi.

Cukup tambahkan metode berikut di Anda AndroidTestCase:

/**
 * @return The {@link Context} of the test project.
 */
private Context getTestContext()
{
    try
    {
        Method getTestContext = ServiceTestCase.class.getMethod("getTestContext");
        return (Context) getTestContext.invoke(this);
    }
    catch (final Exception exception)
    {
        exception.printStackTrace();
        return null;
    }
}

Kemudian telepon getTestContext()kapan saja Anda mau. :)

Timothée Jeannin
sumber
2
Bekerja dengan sempurna untuk saya dan saya memuat aset menggunakan Context baik dari AndroidTestCase melalui metode ini, atau ActivityInstrumentationTestCase2.getInstrumentation () .getContext () lalu getResources () .getAssets ()
Andrew Mackenzie
Dapatkah Anda berspekulasi mengapa mereka menyembunyikannya? Jika kita menggunakan teknik ini, dapatkah mereka menghilangkan metode ini di rilis selanjutnya (melanggar kode pengujian kita)?
Andrew Shepherd
1
Saya mendapatkanjava.lang.NoSuchMethodException: android.test.ServiceTestCase.getTestContext()
kurdtpage
4

Pembaruan: AndroidTestCase Kelas ini tidak digunakan lagi di API level 24. Gunakan InstrumentationRegistrysebagai gantinya. Pengujian baru harus ditulis menggunakan Android Testing Support Library. Tautan ke pengumuman

Anda harus memperluas dari AndroidTestCase, bukan TestCase.

Ikhtisar Kelas AndroidTestCase
Perluas ini jika Anda perlu mengakses Sumber Daya atau hal lain yang bergantung pada Konteks Aktivitas.

AndroidTestCase - Pengembang Android

eslamb
sumber
4

Jika Anda ingin mendapatkan konteksnya dengan Kotlin dan Mockito, Anda dapat melakukannya dengan cara berikut:

val context = mock(Context::class.java)

Saya harap ini membantu Anda

Juanes 30
sumber
mendapatkan null dalam konteks?
Deven
Dan jangan lupa untuk memberi anotasi Anda menguji kelas dengan @RunWith (MockitoJUnitRunner :: class)
USMAN osman
2

Ini adalah cara yang benar untuk mendapatkan Konteks. Metode lain sudah tidak digunakan lagi

import androidx.test.platform.app.InstrumentationRegistry

InstrumentationRegistry.getInstrumentation().context
tomrozb
sumber
2
import androidx.test.core.app.ApplicationProvider;

    private Context context = ApplicationProvider.getApplicationContext();
eoinzy
sumber
1

Bagi mereka yang mengalami masalah ini saat membuat tes otomatis, Anda harus melakukan ini:

    Context instrumentationContext;

    @Before
    public void method() {

        instrumentationContext = InstrumentationRegistry.getInstrumentation().getContext();

        MultiDex.install(instrumentationContext);
    }
Sebastien FERRAND
sumber
0

Jawaban lainnya sudah ketinggalan zaman. Sekarang, setiap kali Anda memperluas AndroidTestCase, ada objek Konteks mContext yang dapat Anda gunakan.

Yoni Keren
sumber