在多进程Android应用程序中注入依赖项

时间:2016-02-18 08:19:35

标签: android functional-testing android-espresso multiple-processes

TLDR:我正在开发一个在多个进程中运行的应用程序。出于UI测试的目的,我想注入一个假的API依赖项,使应用程序在独立于网络交互的测试下运行,但是,这似乎不适用于多进程设置。

我正在使用this post中描述的方法,所以我实现了一个自定义AndroidJUnitRunner,它使用模拟依赖项(让它为MockApplication)而不是具有真正依赖项的应用程序来实例化应用程序(让它为RealApplication)。它确实有效,我的应用程序从主进程查询伪API接口。

然而,我的应用程序使用多个进程,例如有一个数据处理Service,它在自己的进程中运行,并且仅从应用程序代码的startService调用开始。出于某种原因,此过程使用RealApplication的实例运行,没有任何模拟依赖项。

有什么方法可以让它发挥作用吗?我尝试深入研究负责应用程序实例化的Android代码,但还没找到任何特别有用的东西。

P.S。我正在使用Dagger 2进行DI,但这可能不太相关。

2 个答案:

答案 0 :(得分:1)

问题是您的自定义应用程序类没有覆盖AndroidManifest.xml中的真实应用程序。

您只是告诉仪器测试运行器运行您的自定义应用程序类,但如果应用程序启动另一个进程,Android框架甚至不知道它需要运行您的自定义应用程序类而不是真正的应用程序类

因此,我建议您在AndroidManifest.xml任务执行期间将应用程序类覆盖到connectedAndroid中的自定义类,因此您的应用程序将使用自定义类,即使没有黑客攻击测试运行器以及新进程何时开始。

答案 1 :(得分:0)

我也在努力解决这个问题,因为我需要模拟从自己进程中启动的Service发出的网络调用。

要在测试期间在应用的每个流程中使用自定义Application对象(MockApplication),解决方案是在manifestPlaceholders的帮助下在AndroidManifest.xml中注入构建变量。

我在build.gradle中定义了两种产品风格:

productFlavors {
    mock {
        manifestPlaceholders = [application:".MockApplication"]
    }
    prod {
        manifestPlaceholders = [application:".RealApplication"]
    }

}
  • prod:将在清单
  • 中设置真正的Application对象(RealApplication)
  • mock:将模拟的Application对象(MockApplication)设置为模拟网络调用

AndroidManifest.xml中,使用变量“application”,如下所示:

<application 
    android:label="@string/app_name"
    android:name="${application}">

现在,当您想使用MockApplication时,只需使用构建变体“mockDebug”运行您的检测测试