我们如何在Robolectric中访问应用程序的上下文?


Answers:


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)用于测试?
Eugen Martynov

4
是的..我添加了...但是它仍然返回null
user1667968 2012年

1
我已经完成了您提到的所有内容,但仍然为null。我可能还会想念其他东西吗?
Moises Jimenez 2015年

13
另外,请确保不要RuntimeEnvironment.application在静态代码中使用(例如带注释的方法@BeforeClass),因为Robolectric可能此时不会初始化,其值将为null
sfera 2015年

1
同样,这也会导致应用程序在测试之间流血..这可能是不希望的
克里斯(Chris

26

您可以使用

RuntimeEnvironment.application

4
在RoboElectric 3.0中,不再存在Roboelectric.application,因此这可能是最好的答案
kenyee

19

用这个:

Robolectric.application

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

对于截至2019年的最新Robolectric 4.3`

ShadowApplication.getInstance()

`和

机器人应用

都被描述。所以我正在使用

Context context = RuntimeEnvironment.systemContext;

获取上下文。


5

要获取应用程序上下文,您必须执行以下操作:

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

2

这对我来说适用于Robolectric 3.5.1: ShadowApplication.getInstance().applicationContext


请注意,看起来4.0版本将删除此方法。最好坚持使用RuntimeEnvironment.applicationRuntimeEnvironment.application.getApplicationContext()如果它对您有用。

2

从7月21日的4.0-alpha-3版本开始,它们已删除 ShadowApplication.getApplicationContext()。坚持使用RuntimeEnvironment.application.getApplicationContext()注释任何测试@RunWith(RobolectricTestRunner::class)

顺便说一句,他们当前的指南中有一个使用以下示例获取字符串资源的示例:

final Context context = RuntimeEnvironment.application;

(注意,对于的javadoc RuntimeEnvironmentShadowApplication目前反映非字母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());
}

}

确保在“运行/调试配置”工作目录中将目录设置为:$ MODULE_DIR $ 在此处输入图片说明 在此处输入图片说明


1

相比直接使用Robolectric.getShadowApplication(),使用起来更安全Robolectric.application


但是,如果我需要访问自定义应用程序的某些自定义属性,该怎么办?看来我无法从阴影应用程序中获取真实对象。
Denis Kniazhev 2015年

@DenisKniazhev对不起,我无法为您回答。在开始使用Robolectric之后不久,我们开始使用Travis作为CI,但它们的表现并不理想。我的猜测是,您可以将其强制转换为应用程序,或者可能需要创建自定义运行程序才能以这种方式访问​​它。祝你好运
drspaceboo 2015年

谢谢,目前Robolectric.application
为止

6
Robolectric.getShadowApplication()不可用
IgorGanapolsky'9

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 studio中的volley模块中添加依赖项,如下所示:

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


1

对于您的情况,我认为您应该牢记您实际测试的内容。有时遇到无法测试的问题代码或看似无法验证的代码也许是需要进行重构你的代码的标志。

对于API调用响应,您可能不想测试API调用本身。可能没有必要测试是否可以从任意Web服务发送/接收信息,而是测试您的代码以预期的方式处理和处理您的响应。

在这种情况下,最好重构您要测试的代码。将响应解析/处理分解到另一个接受简单类的类,String并通过注入样本字符串响应对该类进行测试。

这是或多或少以下的想法单一职责依赖倒置(将小号dSOLID


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,因为when()部分在sut初始化之后。它可能对您有些帮助。

我也有

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

在课程开始时

 when(mockApplication.getApplicationContext()).thenReturn(RuntimeEnvironment.application.getApplicationContext()); works
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.