在Android junit测试案例中获取测试项目的上下文


108

有谁知道如何在Android junit测试案例中获得Test项目的上下文(扩展了AndroidTestCase)。

注意:该测试不是仪器测试。

注意2:我需要测试项目的上下文,而不是要测试的实际应用程序的上下文。

我需要它来从测试项目中的资产中加载一些文件。


您为什么不能只使用InstrumentationTestCase?
yorkw 2011年

1
因为我在测试服务,而不是UI。
2011年

1
有一个更好的答案在这里找到:[使用AndroidTestCase,而不是一个JUnit测试] [1] [1]:stackoverflow.com/questions/3170706/...
海梅·波特罗

Answers:


136

Android测试支持库提供了一种新方法(当前为androidx.test:runner:1.1.1)。Kotlin更新示例:

class ExampleInstrumentedTest {

    lateinit var instrumentationContext: Context

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

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

如果您还希望运行应用程序上下文:

InstrumentationRegistry.getInstrumentation().targetContext

完整的运行示例:https : //github.com/fada21/AndroidTestContextExample

看这里:getTargetContext()和getContext(在InstrumentationRegistry上)有什么区别?


最后是有关如何在InstrumentationTest中使用JUnit4的答案。经过数小时的搜索。一定喜欢Android开发。
Fabian Zeindl

1
真好!tx(请注意,您的班级成员中有错字)
Greg

1
有人可以帮忙在gradle文件中添加哪些依赖项才能使其正常工作吗?
格雷格

1
不要忘记添加compile "com.android.support.test:runner:1.0.1"到您的gradle
egorikem '18

2
已弃用,请InstrumentationRegistry.getInstrumentation().context改用。
艾伦·韦洛索

37

经过一些研究,唯一可行的解​​决方案似乎是约克所指出的。您必须扩展InstrumentationTestCase,然后可以使用getInstrumentation()。getContext()访问测试应用程序的上下文-这是使用以上建议的简短代码段:

public class PrintoutPullParserTest extends InstrumentationTestCase {

    public void testParsing() throws Exception {
        PrintoutPullParser parser = new PrintoutPullParser();
        parser.parse(getInstrumentation().getContext().getResources().getXml(R.xml.printer_configuration));
    }
}

7
是的,但是在简单的JUnit测试中Android不提供对测试项目上下文的访问权限似乎很可笑。上下文在AndroidTestCase.mTestContext中,但是是私有的。我不明白为什么。
2012年

@peceps Full Ack-但这就是事实,我也不喜欢;)
AgentKnopf 2012年

25

正如您可以在AndroidTestCase源代码中阅读的那样,该getTestContext()方法是隐藏的。

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

您可以@hide使用反射绕过注释。

只需在您的中添加以下方法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;
    }
}

然后getTestContext()随时拨打电话。:)


2
对我来说非常完美,我使用Context通过此方法使用AndroidTestCase或ActivityInstrumentationTestCase2.getInstrumentation().getContext()然后再使用getResources().getAssets()加载资产
Andrew Mackenzie

您能推测他们为什么将其隐藏吗?如果我们使用这种技术,他们是否可以在以后的版本中删除该方法(破坏我们的测试代码)?
Andrew Shepherd 2014年

1
我得到java.lang.NoSuchMethodException: android.test.ServiceTestCase.getTestContext()
kurdtpage '18

4

更新: AndroidTestCase在API级别24中不推荐使用该类InstrumentationRegistry。请改用。新的测试应使用Android测试支持库编写。链接到公告

您应该从AndroidTestCase而不是TestCase扩展。

AndroidTestCase类概述
如果您需要访问“资源”或其他依赖于“活动上下文”的事物,请对其进行扩展。

AndroidTestCase-Android开发人员


4

如果要使用Kotlin和Mockito获取上下文,可以按照以下方式进行操作:

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

希望对您有帮助


在上下文中为空?
德文

并且不要忘记使用@RunWith(MockitoJUnitRunner :: class)注释您的测试类
USMAN osman

2

这是获取上下文的正确方法。其他方法已被弃用

import androidx.test.platform.app.InstrumentationRegistry

InstrumentationRegistry.getInstrumentation().context

2
import androidx.test.core.app.ApplicationProvider;

    private Context context = ApplicationProvider.getApplicationContext();

1

对于那些在创建自动化测试时遇到这些问题的人,您必须这样做:

    Context instrumentationContext;

    @Before
    public void method() {

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

        MultiDex.install(instrumentationContext);
    }

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.