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

有人知道如何在 Android junit 测试用例(扩展 AndroidTestCase)中获得 测试项目的上下文吗。

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

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

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

104232 次浏览

经过一些研究,唯一可行的解决方案似乎是约克已经指出的那个。您必须扩展 InstrumentationTestCase,然后才能使用 getInstruments ()访问测试应用程序的上下文。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));
}
}

正如您可以在 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()。 :)

Android 测试支持库(目前为 androidx.test:runner:1.1.1)有了新的方法:

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 上)的区别是什么?

更新: AndroidTestCase此类在 API 级别24中已被弃用。 使用 InstrumentationRegistry代替。新的测试应该使用 Android 测试支持库来编写

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

AndroidTestCase 类概述
如果您需要访问参考资料或其他依赖于活动上下文的内容,请扩展此选项。

AndroidTestCase-Android 开发者

其他的答案都过时了。现在,每次扩展 AndroidTestCase 时,都可以使用 mContext 对象。

如果你想了解 Kotlin 和 Mockito 的背景,你可以这样做:

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

这是为了更正获取上下文的方法。其他方法已经不推荐使用

import androidx.test.platform.app.InstrumentationRegistry


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


private Context context = ApplicationProvider.getApplicationContext();

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

    Context instrumentationContext;


@Before
public void method() {


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


MultiDex.install(instrumentationContext);
}

@ RunWith (AndroidJUnit4.class)允许您使用 Android 上下文

/**
* Instrumented test, which will execute on an Android device.
*
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
*/
@RunWith(AndroidJUnit4.class)
public class ExampleInstrumentedTest {
@Test
public void useAppContext() {
// Context of the app under test.
Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
assertEquals("com.android.systemui", appContext.getPackageName());
}




}

你甚至可以使用 runOnMainSync在主线程上运行它。下面是完整的解决方案:

@RunWith(AndroidJUnit4::class)
class AwesomeViewModelTest {


@Test
fun testHandler() {


getInstrumentation().runOnMainSync(Runnable {
val context = InstrumentationRegistry.getInstrumentation().targetContext


// Here you can call methods which have Handler


       

})
}




}

添加 Mocito 库

testImplementation 'junit:junit:4.13.2'
testImplementation 'androidx.test:core:1.4.0'
testImplementation 'org.mockito:mockito-core:3.10.0'

添加注释调用@Mock,例如上下文

@RunWith(MockitoJUnitRunner::class)

类 EmailValidatorTest {

@Mock
private lateinit var context: Context


lateinit var utils:Utils


@Before
fun launch()
{
utils=Utils(context)
}


@Test
fun emailValidator_NullEmail_ReturnsFalse() {
assertFalse(utils.isValidEmail(null))
}

}