我目前正在开发Android MVP应用程序,并且我试图将我的依赖项分离到不同的Dagger2模块中。
我遇到的问题是在单位测试时间内更换模块。方案如下:
代码如下:
@Singleton
@Component(modules = {LoginModule.class, HTTPModule.class})
public interface LoginComponent {
}
@Module(includes = {HTTPModule.class})
public class LoginModule {
@Provides
@Singleton
public MyThing provideMyThing(OkHttpClient client) {
// Do things with it
}
}
@Module
public class HTTPModule {
@Provides
@Singleton
public OkHttpClient provideOkHttpClient(){
// Return the OkHttpClient
}
}
问题是,在测试时我需要更改返回的OkHttpClient(通过让它接受所有证书,就像我在JVM上运行它不接受LetsEncrypt证书一样)。
另外我需要这个,因为我需要声明MyTest.class
可以注入模块,而MyTest.class
位于app/src/test/
文件夹下,它不可见放在app/src/main/
下的类。到目前为止我所做的是将Component和模块复制并粘贴到/test/
文件夹,并在那里进行注入的类声明。但我知道必须有一种正确的方法来实现我所寻找的目标。
我尝试的另一件事是使用自定义范围注释方法(创建@TestScope
注释)。但是,这导致我遇到了之前评论过的相同问题:我无法使MyTest.class
对组件可见,因为它位于/test/
文件夹下。
我已经检查了其他类似的问题,例如this one和this another one,但最后一个问题是使用Robolectric运行测试,现在我已经能够仅使用JUnit4测试我的大部分代码(Android Studio 2-Beta 8)。
如果有人能指出我正确的方向,我会非常感激。
提前致谢!
答案 0 :(得分:0)
您正在以一种仍然保持代码紧密耦合的方式使用依赖注入。一般来说,您希望您的依赖项是接口而不是实际的类。这使您的代码保持良好和松散,易于阅读,修改和维护。
隐藏界面背后的网络操作,以便您随时修改网络实施。这可以用于测试 - 在您的情况下,但如果您将来需要或不需要更改任何其他代码,它还允许您切换网络库。
尝试这样的事情:
@Module
public class HTTPModule {
@Provides
@Singleton
public NetworkProvider provideNetworkProvider(){
// Return the Network provider
}
}
网络抽象层:
public interface NetworkProvider {
// Methods to send requests and receive async responses
}
OkHttp实现:
public class OkHttpNetworkProvider implements NetworkProvider {
// Implement NetworkProvider. This is the only class that
// knows about OkHttp and its components
}
现在您可以创建NetworkProvider
的模拟版本并将其用于测试,无论是通过测试模块还是直接测试。