在应用程序中模拟Android的ApplicationContext

5

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

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

测试类大致如下

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

application.applicationContext 始终返回 null,然后引发了 IllegalStateException

有解决办法吗?

2个回答

3
我认为这里有两种可能性。我使用了第二种,并知道它是可行的,第一种是我的猜测。
(1)
您正在模拟Application。然后您尝试使用其applicationContext,但您没有模拟它。您需要对其进行模拟:
val context  =  Mockito.mock(Context::class.java)
Mockito.`when`(application.applicationContext).thenReturn(context)

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

最后,您需要告诉Android使用此运行器:

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


由此可知,在您的仪器测试中,应用程序上下文将是TestMyApplication的实例。

最后我扩展了我的ViewHolder类,它接收上下文对象作为参数,在我的测试类中我对其进行了模拟(@mock lateinit var context context)。我会尝试你的解决方案,谢谢。 - Karate_Dog

0

可以通过使用Fake来实现这一点。假设您想模拟Application类实现的接口。

// main
interface AppInitializer {
   val isUserLoggedIn: Boolean
}

class MyApplication : AppInitializer {
    override val isUserLoggedIn: Boolean
        get() = // ...
}

// test
class FakeMyApplication : AppInitializer {
    override val isUserLoggedIn: Boolean
        get() = true

   // you need to override this
   override fun getApplicationContext(): Context {
        return this
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接