Android 模拟应用程序内的应用程序上下文

Kar*_*Dog 5 android unit-testing mockito android-viewmodel

我在创建测试类时遇到问题。基本上我想测试执行网络调用的视图模型类。使用 dagger 注入类网络组件需要上下文参数来检查连接,这是我的视图模型:

class MyViewModel(application: Application): AndroidViewModel(application) {
   @Inject lateinit var network: NetworkService
    init {
        DaggerNetworkComponent.builder().networkModule(NetworkModule(application.applicationContext))
        .build().inject(this)
        network.callNetwork()
    } 
}
Run Code Online (Sandbox Code Playgroud)

测试类是这样的

lateinit var myViewModel: MyViewModel
@Test
fun testMyNetwork() { 
   application =  Mockito.mock(Application::class.java)
   myViewModel = MyViewModel(application)
}
Run Code Online (Sandbox Code Playgroud)

总是application.applicationContext返回 null,然后返回IllegalStateException

有什么解决办法吗?

ror*_*ror 3

我认为这里有两种可能性。我用过第二个,知道它有效,第一个是我的猜测。

(1)

你在嘲笑应用程序。然后你尝试使用它,applicationContext但是你没有嘲笑它。您还需要模拟它:

val context  =  Mockito.mock(Context::class.java)
Mockito.`when`(application.applicationContext).thenReturn(context)
Run Code Online (Sandbox Code Playgroud)

(2)

假设 1) 您的测试是仪器测试 2) 您正在使用 的子类Application- 例如,MyApplication.

然后,您必须创建它的子类 - 例如,TestMyApplication. 下一步是创建 的子类AndroidJUnitRunner,可能如下所示:

public class MyInstrumentationTestRunner extends AndroidJUnitRunner {
    @Override
    public Application newApplication(ClassLoader cl, String className, Context context)
            throws InstantiationException, IllegalAccessException, ClassNotFoundException {
        return Instrumentation.newApplication(TestMyApplication.class, context);
    }
}
Run Code Online (Sandbox Code Playgroud)

最后,你需要告诉 android 使用这个运行器:

allprojects {
    ext {
        ....
        testInstrumentationRunner = "com...MyInstrumentationTestRunner"
    }
}

Run Code Online (Sandbox Code Playgroud)

由于上述原因,应用程序上下文将是仪器测试中 TestMyApplication 的实例。