Bagaimana kita bisa mengakses konteks aplikasi di Robolectric?


112

Sebenarnya, saya perlu mendapat respons dari panggilan API, untuk itu saya memerlukannya Context.

Jawaban:


218

Memperbarui.

Cukup gunakan untuk versi 1.x dan 2.x:

Robolectric.application;

Dan untuk versi 3.x:

RuntimeEnvironment.application;

Dan untuk versi 4.x:

  • tambahkan ke build.gradlefile Anda :

    testImplementation 'androidx.test:core:1.0.0'
    
  • ambil konteksnya dengan:

    ApplicationProvider.getApplicationContext()
    

11
Apakah Anda menempatkan @RunWith (RobolectricTestRunner.class) untuk pengujian Anda?
Eugen Martynov

4
Ya .. Saya menambahkan ... tapi tetap saja mengembalikan null
user1667968

1
Saya telah melakukan semua yang Anda sebutkan dan masih mendapatkan nol. Ada lagi yang mungkin saya lewatkan?
Moises Jimenez

13
Juga pastikan bahwa Anda tidak menggunakan RuntimeEnvironment.applicationkode statis (seperti metode yang dianotasi @BeforeClass) karena Robolectric mungkin tidak akan diinisialisasi pada saat itu dan nilainya akan seperti itu null.
sfera

1
Hal ini juga menyebabkan aplikasi berdarah di antara pengujian .. yang mungkin tidak diinginkan
Chris

26

Kamu bisa memakai

RuntimeEnvironment.application

4
di RoboElectric 3.0, Roboelectric.application tidak ada lagi, jadi ini mungkin jawaban terbaik
kenyee


16

Menambahkan

testImplementation "androidx.test:core-ktx:${deps.testrunner}"

Dan gunakan:

private val app = ApplicationProvider.getApplicationContext()

impor androidx.test.core.app.ApplicationProvider
luckyhandler

val appContext = ApplicationProvider.getApplicationContext <Context> ()
luckyhandler

2
Ini adalah jawaban yang benar dengan Robolectric terbaru. Metode lain yang disebutkan di sini tidak digunakan lagi atau dihapus.
Gabor

7

Untuk Robolectric 4.3 terbaru saat ini di tahun 2019 '

ShadowApplication.getInstance ()

`dan

Roboletric.application

keduanya dikecualikan. Jadi saya menggunakan

Context context = RuntimeEnvironment.systemContext;

untuk mendapatkan Konteks.


5

Untuk mendapatkan konteks aplikasi, Anda harus melakukan hal berikut:

  1. anotasi @RunWith (RobolectricTestRunner.class)
  2. RuntimeEnvironment.application.getApplicationContext ()

2

Ini berfungsi untuk saya dengan Robolectric 3.5.1: ShadowApplication.getInstance().applicationContext


Perhatikan bahwa sepertinya rilis 4.0 akan menghapus metode ini; lebih baik untuk tetap bersama RuntimeEnvironment.applicationatau RuntimeEnvironment.application.getApplicationContext()jika itu berhasil untuk Anda.
qix

2

Pada rilis 4.0-alpha-3 pada 21 Juli, mereka dihapus ShadowApplication.getApplicationContext() . Tetap gunakan RuntimeEnvironment.application.getApplicationContext()untuk pengujian apa pun yang dianotasi @RunWith(RobolectricTestRunner::class).

Selain itu, panduan mereka saat ini memiliki contoh mendapatkan resource string menggunakan:

final Context context = RuntimeEnvironment.application;

(Perhatikan bahwa javadocs untuk RuntimeEnvironmentdan ShadowApplicationsaat ini mencerminkan rilis non-alfa 3.x.)


2

Pertama tambahkan yang berikut ini ke Anda build.gradle:

testImplementation 'androidx.test:core:1.2.0'

lalu gunakan:

ApplicationProvider.getApplicationContext() as Application


2

Dalam beberapa kasus, Anda mungkin memerlukan konteks aplikasi Anda, bukan konteks default Robolectris. Misalnya, jika Anda ingin mendapatkan nama paket Anda. Secara default, Robolectric akan mengembalikan org.robolectric.defaultnama paket Anda . Untuk mendapatkan nama paket asli Anda, lakukan hal berikut:

build.gradle

testImplementation 'org.robolectric:robolectric:4.2.1'

Kelas tes Anda:

@RunWith(RobolectricTestRunner.class)
@Config( manifest="AndroidManifest.xml")
public class FooTest {

@Test
public void fooTestWithPackageName(){
    Context context = ApplicationProvider.getApplicationContext();
    System.out.println("My Real Package Name: " + context.getPackageName());
}

}

Pastikan bahwa direktori Kerja Konfigurasi Run / Debug Anda disetel ke: $ MODULE_DIR $ masukkan deskripsi gambar di sini masukkan deskripsi gambar di sini


1

Ini lebih aman digunakan Robolectric.getShadowApplication()daripada menggunakan Robolectric.applicationsecara langsung.


Tetapi bagaimana jika saya perlu mengakses beberapa properti kustom dari aplikasi kustom saya? Sepertinya saya tidak bisa mendapatkan objek sebenarnya dari aplikasi bayangan.
Denis Kniazhev

@DenisKniazhev Maaf saya tidak bisa menjawabnya untuk Anda. Tak lama setelah kami mulai menggunakan Robolectric, kami mulai menggunakan Travis sebagai CI kami, dan mereka tidak berfungsi dengan baik. Dugaan saya adalah Anda dapat mentransmisikannya ke aplikasi Anda atau Anda mungkin perlu membuat runner khusus untuk mendapatkan akses ke sana. Semoga sukses
drspaceboo

Terima kasih, untuk saat ini saya baru saja berpegang padaRobolectric.application
Denis Kniazhev

6
Robolectric.getShadowApplication () tidak tersedia
IgorGanapolsky

1

Setuju dengan jawaban @EugenMartynov dan @rds ....

Contoh cepat dapat ditemukan di Volley-Marshmallow-Release

di NetworkImageViewTest.java

// mNIV = new NetworkImageView(Robolectric.application); mNIV = new NetworkImageView(RuntimeEnvironment.application);

Tautan Volley tersedia https://android.googlesource.com/platform/frameworks/volley/+/marshmallow-release

Anda harus menambahkan dependensi dalam modul volley di android studio sebagai:

dependencies { testCompile 'junit:junit:4.12' testCompile 'org.mockito:mockito-core:1.10.19' testCompile 'org.robolectric:robolectric:3.1.2' }


1

Dalam kasus Anda, saya pikir Anda harus memperhatikan apa yang sebenarnya Anda uji. Kadang-kadang berlari ke masalah diuji kode atau kode yang tampaknya diuji adalah tanda bahwa mungkin kode Anda perlu refactored.

Untuk respons panggilan API, Anda mungkin tidak ingin menguji panggilan API itu sendiri. Mungkin tidak perlu untuk menguji apakah mungkin untuk mengirim / menerima informasi dari sembarang layanan web, tetapi kode Anda menangani dan memproses respons Anda dalam cara yang diharapkan.

Dalam hal ini mungkin lebih baik untuk memfaktor ulang kode yang Anda coba uji. Keluarkan respons parsing / penanganan ke kelas lain yang menerima sederhana Stringdan lakukan pengujian Anda pada kelas itu dengan memasukkan respons string sampel.

Ini kurang lebih mengikuti gagasan Single Responsibility and Dependency Inversion (The S dan D in SOLID )


1

Oke, jadi saya tahu banyak orang lain yang mengatakan jawaban ini sebelumnya dan mungkin sudah ketinggalan zaman

    when(mockApplication.getApplicationContext()).thenReturn(RuntimeEnvironment.application);
    when(mockApplication.getFilesDir()).thenReturn(RuntimeEnvironment.application.getFilesDir());

    sharedPref = RuntimeEnvironment.application.getSharedPreferences(KEY_MY_PREF, Context.MODE_PRIVATE);
    sut = new BundleManagerImpl(mockApplication,
            processHtmlBundle, resultListener, sharedPref);

Saya mendapatkan null, karena when () part adalah SETELAH inisialisasi sut. Mungkin membantu beberapa dari Anda.

juga saya punya

@RunWith(CustomRobolectricTestRunner.class)
@Config(constants = BuildConfig.class)

di awal kelas

Juga

 when(mockApplication.getApplicationContext()).thenReturn(RuntimeEnvironment.application.getApplicationContext()); works
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.