Android Instrumented测试中Toothpick依赖注入成员失败问题
解决Toothpick在Android Instrumented测试中无法注入测试类自身成员的问题
首先,我注意到你的核心问题是:测试类中用@Inject标注的mContext始终为null,但其他类的注入都正常。这大概率是因为测试类没有被Toothpick的注解处理器处理,同时还有一些测试Scope的配置细节需要调整。
问题根源分析
- 注解处理器未覆盖测试目录:你的Gradle配置中,只给主工程添加了Toothpick的注解处理器,但
androidTest目录下的测试类并没有被注解处理器扫描,导致Toothpick无法生成测试类的注入代码。 - 测试类的Scope绑定细节:虽然你手动创建了Scope并绑定了Context,但由于注解处理器没处理测试类,Toothpick不知道要注入这个类的哪些成员。
具体解决方案
1. 完善Gradle配置,给测试目录添加注解处理器
修改你的app/build.gradle,在测试相关依赖中添加Toothpick的注解处理器,确保测试类能被扫描处理:
dependencies { // 原有的主工程依赖保持不变 implementation 'com.github.stephanenicolas.toothpick:toothpick-runtime:1.1.3' implementation 'com.github.stephanenicolas.toothpick:smoothie:1.1.3' annotationProcessor 'com.github.stephanenicolas.toothpick:toothpick-compiler:1.1.3' // 测试相关依赖新增注解处理器 androidTestImplementation 'com.android.support.test:runner:1.0.2' androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' androidTestAnnotationProcessor 'com.github.stephanenicolas.toothpick:toothpick-compiler:1.1.3' androidTestImplementation 'com.github.stephanenicolas.toothpick:toothpick-testing:1.1.3' }
2. 优化测试类的Scope和注入逻辑
简化测试类的Scope管理,同时确保注入逻辑正确,修改后的测试代码如下:
@RunWith(AndroidJUnit4.class) public class ExampleInstrumentedTest { private static final String LOG_TAG = ExampleInstrumentedTest.class.getName(); @Inject Context mContext; @Test public void useAppContext() throws Exception { Context appContext = InstrumentationRegistry.getTargetContext(); assertThat(appContext.getPackageName(), startsWith("com.honeybeeapp.toothpicktest.mytoothpickapplication")); SimpleApp application = (SimpleApp) appContext.getApplicationContext(); // 打开绑定application与测试类的专属Scope Scope testScope = Toothpick.openScopes(application, ExampleInstrumentedTest.class); // 安装测试Module,绑定Context到application实例 testScope.installTestModules(new Module() {{ bind(Context.class).toInstance(application); }}); // 注入测试类自身 Toothpick.inject(this, testScope); assertTrue(mContext != null); // 现在应该能成功注入了 Log.d(LOG_TAG, "Injected successfully, mContext: " + mContext); } }
额外注意事项
- 执行
clean和rebuild项目,确保注解处理器重新生成所有必要的注入代码。 - 如果你使用的是Toothpick 1.x版本,即使
@Inject成员是private也能被注入,但如果仍有问题,可以临时改为public验证是否是访问权限导致的。
内容的提问来源于stack exchange,提问作者Diederik
相关产品推荐
相关产品推荐

