Як ми можемо отримати доступ до контексту програми у Robolectric?


Відповіді:


218

Оновлення.

Просто використовуйте для версій 1.x та 2.x:

Robolectric.application;

А для версії 3.x:

RuntimeEnvironment.application;

А для версії 4.x:

  • додати до build.gradleфайлу:

    testImplementation 'androidx.test:core:1.0.0'
    
  • отримати контекст за допомогою:

    ApplicationProvider.getApplicationContext()
    

11
Ви поставили @RunWith (RobolectricTestRunner.class) для своїх тестів?
Євген Мартинов

4
Так ... Я додав ... але все-таки повертається null
користувач1667968

1
Я зробив усе, про що ви згадали, і досі стає недійсним. Що-небудь ще мені може бути не вистачає?
Мойсей Хіменес

13
Також переконайтеся, що ви не використовуєте RuntimeEnvironment.applicationв статичному коді (як, наприклад, анотовані методи @BeforeClass), оскільки Robolectric, ймовірно, не буде ініціалізовано в цій точці, і значення будеnull .
sfera

1
Також це призводить до того, що додаток кровоточить між тестами .. що може бути небажаним
Кріс

26

Можна використовувати

RuntimeEnvironment.application

4
у RoboElectric 3.0, Roboelectric.application більше не існує, тому це, мабуть, найкраща відповідь
kenyee


16

Додайте

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

І використовуйте:

private val app = ApplicationProvider.getApplicationContext()

import androidx.test.core.app.ApplicationProvider
luckyhandler

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

2
Це правильна відповідь з найновішим Robolectric. Інші методи, згадані тут, є застарілими або усуненими.
Габор

7

Для останнього Robolectric 4.3 станом на 2019 рік `

ShadowApplication.getInstance ()

Roboletric.приклад

обидва знецінені. Так я і використовую

Context context = RuntimeEnvironment.systemContext;

щоб отримати контекст.


5

Щоб отримати контекст програми, потрібно зробити наступне:

  1. примітка @RunWith (RobolectricTestRunner.class)
  2. RuntimeEnvironment.application.getApplicationContext ()

2

Це працює для мене з Robolectric 3.5.1: ShadowApplication.getInstance().applicationContext


Зауважте, що, схоже, випуск 4.0 видалить цей метод; краще дотримуватися RuntimeEnvironment.applicationабо RuntimeEnvironment.application.getApplicationContext()якщо його працює для вас.
qix

2

Станом на випуск 4.0-альфа-3 21 липня їх видалили ShadowApplication.getApplicationContext() . Дотримуйтесь RuntimeEnvironment.application.getApplicationContext()будь-яких тестів, позначених за допомогою @RunWith(RobolectricTestRunner::class).

На відміну від їх поточного посібника є приклад отримання рядкових ресурсів за допомогою:

final Context context = RuntimeEnvironment.application;

(Зауважте, що javadocs для RuntimeEnvironmentта в ShadowApplicationданий час відображають не-альфа-версію 3.x.)


2

Спочатку додайте наступне до свого build.gradle:

testImplementation 'androidx.test:core:1.2.0'

тоді використовуйте:

ApplicationProvider.getApplicationContext() as Application


2

У деяких випадках вам може знадобитися контекст додатка замість контексту Robolectris за замовчуванням. Наприклад, якщо ви хочете отримати назву вашого пакета. За замовчуванням Robolectric поверне вам org.robolectric.defaultім'я пакета. Щоб отримати справжнє ім'я пакета, виконайте наступне:

build.gradle

testImplementation 'org.robolectric:robolectric:4.2.1'

Ваш тестовий клас:

@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());
}

}

Переконайтеся, що у вашому робочому каталозі Run / Debug Configurationtions встановлено значення: $ MODULE_DIR $ введіть тут опис зображення введіть тут опис зображення


1

Безпечніше використовувати, Robolectric.getShadowApplication()а не використовувати Robolectric.applicationбезпосередньо.


Але що робити, якщо мені потрібно отримати доступ до деяких спеціальних властивостей мого користувальницького додатка? Здається, я не можу отримати реальний об’єкт із тіньового додатку.
Денис Княжев

@DenisKniazhev Вибачте, я не можу відповісти на це за вас. Незабаром після того, як ми почали використовувати Robolectric, ми почали використовувати Travis як наш CI, і вони не грають чудово. Я здогадуюсь, що ви можете або передати це програмі, або вам може знадобитися зробити спеціальний бігун, щоб отримати доступ до нього таким чином. Найкраща удача
drspaceboo

Дякую, наразі я тільки що Robolectric.application
притримався

6
Robolectric.getShadowApplication () недоступний
IgorGanapolsky

1

Погоджуйтесь з відповідями @EugenMartynov та @rds ....

Короткий приклад можна знайти на Volley-Marshmallow-Release

в NetworkImageViewTest.java

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

Волейбольне посилання доступне https://android.googlesource.com/platform/frameworks/volley/+/marshmallow-release

Ви повинні додати залежності в модулі залпу в студії Android як:

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


1

У вашому випадку я думаю, ви повинні пам’ятати про те, що саме ви насправді випробовуєте. Іноді наштовхуємось на непереборні питання коду чи, здавалося б, нестабільного коду - це знак того, що, можливо, ваш код потребує відновлення.

Для відповіді на дзвінки API ви, можливо, не захочете тестувати сам виклик API. Можливо, не доведеться перевіряти, чи можна надсилати / отримувати інформацію з будь-якої довільної веб-служби, але, скоріше, ваш код обробляє та обробляє вашу відповідь у очікуваній садибі.

У такому випадку може бути краще переробити код, який ви намагаєтеся перевірити. Виведіть розбір / обробку відповідей на інший клас, який приймає простий Stringі зробіть тестування на цьому класі , вводячи відповіді зразкових рядків.

Це більш-менш слідує ідеям Інверсії єдиної відповідальності та залежності ( S і D у SOLID )


1

Гаразд, тому я знаю, що багато хто говорив цю відповідь раніше і, можливо, вже застарів

    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);

Я отримав null, тому що, коли () частина була ПІСЛЯ ініціалізації sut. Можливо, це допоможе комусь із вас.

також у мене є

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

на початку заняття

Також

 when(mockApplication.getApplicationContext()).thenReturn(RuntimeEnvironment.application.getApplicationContext()); works
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.