- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
使用 DI 的最大优势之一是它使测试变得容易得多(What is dependency injection? 也支持它)。我在其他编程语言上使用过的大多数 DI 框架(.NET 上的 MEF,Obj-C/Swift 上的 Typhoon,Laravel 的PHP 和其他一些平台上的 IoC 容器)允许开发人员在每个组件的单个入口点上注册依赖项,从而防止“创建”对对象本身的依赖项。
读完Dagger 2文档,整个“无反射”业务听起来很棒,但我看不出它如何使测试更容易,因为对象仍然在某种程度上创建它们自己的依赖项。
例如,在 CoffeMaker 示例中:
public class CoffeeApp {
public static void main(String[] args) {
// THIS LINE
CoffeeShop coffeeShop = DaggerCoffeeShop.create();
coffeeShop.maker().brew();
}
}
即使您没有显式调用 new
,您仍然必须创建您的依赖项。
现在,为了更详细的示例,让我们转到 Android Example .如果你打开 DemoActivity
类,你会注意到 onCreate
实现是这样的:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Perform injection so that when this call returns all dependencies will be available for use.
((DemoApplication) getApplication()).component().inject(this);
}
您可以清楚地看到,DI 组件与实际代码没有解耦。总之,您需要在测试用例上模拟/ stub ((DemoApplication) getApplication()).component().inject(this);
(如果可能的话)。
到目前为止,我知道 Dagger 2 非常受欢迎,所以一定有一些我没有看到的东西。那么 Dagger 2 如何让测试类变得更容易呢?我将如何模拟,比方说我的 Activity 所依赖的网络服务类?我希望答案尽可能简单,因为我只对测试感兴趣。
最佳答案
...除了鼓励您首先注入(inject)依赖项之外,这自然会使各个类更易于测试。
我最近听说,Dagger 2 团队仍在考虑改进测试支持的潜在方法 - 尽管无论正在进行什么讨论,它们似乎都不是很公开。
您正确地指出,想要显式使用组件的类依赖于它。所以...注入(inject)该依赖项!您必须“手动”注入(inject)组件,但这应该不会太麻烦。
目前,官方推荐的为测试交换依赖关系的方法是创建一个测试组件来扩展您的生产组件,然后在必要时使用自定义模块。像这样:
public class CoffeeApp {
public static CoffeeShop sCoffeeShop;
public static void main(String[] args) {
if (sCoffeeShop == null) {
sCoffeeShop = DaggerCoffeeShop.create();
}
coffeeShop.maker().brew();
}
}
// Then, in your test code you inject your test Component.
CoffeeApp.sCoffeeShop = DaggerTestCoffeeShop.create();
这种方法适用于您在运行测试时总是想要替换的东西 - 例如您想要针对模拟服务器运行的网络代码,或者用于运行 Espresso 测试的 IdlingResource
实现。
不幸的是,官方方式可能涉及大量样板代码 - 作为一次性的很好,但如果您只想为一组特定的测试交换单个依赖项,那将是一个真正的痛苦。
我最喜欢的 hack 是简单地扩展任何具有您要替换的依赖项的模块,然后覆盖 @Provides
方法。像这样:
CoffeeApp.sCoffeeShop = DaggerCoffeeShop.builder()
.networkModule(new NetworkModule() {
// Do not add any @Provides or @Scope annotations here or you'll get an error from Dagger at compile time.
@Override
public RequestFactory provideRequestFactory() {
return new MockRequestFactory();
}
})
.build();
检查 this gist一个完整的例子。
关于android - Dagger 2 如何让 Android 上的测试更容易?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32487580/
我是一名优秀的程序员,十分优秀!