使用Dagger 2进行依赖项注入意味着您可以注入伪造/模拟对象进行测试。 我曾在我要更新的旧Android应用程序的Espresso测试中使用伪造的AndroidInjector进行此操作,但发现在将Dagger更新到较新版本(从2.14到2.21)后,自定义AndroidInjector不再编译。
我使用的虚假AndroidInjector是基于几年前写的这些博客:
- 使用Dagger的Android注射器进行活动浓缩咖啡测试
- 使用Dagger的Android Injector进行片段浓缩咖啡测试
- https://github.com/SabagRonen/dagger-activity-test-sample
可以在这里找到该想法的另一个版本:
- https://gist.github.com/vaughandroid/3c3c260fc7fcb64a628a55712a87736c
这是一篇简短的文章,介绍了如何针对仍在使用这些文章中的代码的任何人解决此问题(也要感谢这些作者提出这些想法,这是迟来的感谢)。
它不编译...
问题来自对版本2.19中Dagger代码的这些内部更改。
https://github.com/google/dagger/releases/tag/dagger-2.19
简单修复
根据上述文章中的代码,只需进行一些简单的更改(不幸的是,这花了我一段时间才能解决!)。
1.替换不建议使用的注释
@ActivityKey
与
@ClassKey
2. AndroidInjector.Factory和AndroidInjector代码中使用的其他类的通用类型已从
extends Activity> // java // kotlin
至
> // java <*> // kotlin
3. DispatchingAndroidInjector更改了其构造函数签名。 现在,不再有通过类为AndroidInjector.Factory的Provider的Map的单个参数作为类的键,而是使用了String(类名)作为键的Map的附加参数。
因此,在Dagger生成的代码(以及伪造的AndroidInjector)中,方法DispatchingAndroidInjector_Factory.newDispatchingAndroidInjector()也需要此额外参数(即使只是一个空的Map)。
// java (pseudo-code) Map, Provider>> classMap = new HashMap<>( 1 ); // create a custom AndroidInjector.Factory and add it to the provider Provider> provider = ... map.put(MyActivity. class , provider); // empty map to satisfy method signature for newDispatchingAndroidInjector() Map>> stringMap = new HashMap<>(); return DispatchingAndroidInjector_Factory.newDispatchingAndroidInjector(classMap, stringMap);
// kotlin val classMap : Map, Provider>> = mapOf( Pair, Provider>>(T:: class .java, Provider { factory })) // empty map to satisfy method signature for newDispatchingAndroidInjector() val stringMap : Map>> = emptyMap>>() return DispatchingAndroidInjector_Factory.newDispatchingAndroidInjector(classMap, stringMap)
为什么要使用假的AndroidInjector?
使Dagger注入测试依赖项的更常见方法是维护测试组件和测试模块的并行宇宙,以提供伪造的依赖项。 这可以正常工作,并具有不应因Dagger代码的内部更改而中断的优点。 但是,这也意味着需要维护更多样板代码。
翻译自: https://www.javacodegeeks.com/2019/04/update-fake-androidinjector.html