【问题标题】:Dagger 2 injection in Android instrumentation testsAndroid 仪器测试中的 Dagger 2 注入
【发布时间】:2021-10-16 22:33:24
【问题描述】:

我正在尝试在我的 Android 仪器测试中使用 Dagger 2 进行 DI。它适用于主应用程序组件中的类/活动/片段,但我的测试组件似乎缺少一些我找不到的绑定。任何关于如何去做的想法都将不胜感激。我的代码如下所示:

AssetRepositoryTest

public class AssetRepositoryTest {

    @Nested
    @DisplayName("Given a populated database")
    public class PopulatedDatabaseInstance {

        @Inject
        private TestDatabase database;

        @Inject
        private AssetRepository repository;

        @BeforeEach
        public void setup() {
            final TestApplication application = ApplicationProvider.getApplicationContext();
            application.androidInjector().inject(this);
            
            // Setup database
        }
        
        // Tests
    }
}

运行仪器测试我得到以下异常:

java.lang.IllegalArgumentException: No injector factory bound for Class<AssetRepositoryTest.PopulatedDatabaseInstance>

而匕首相关代码如下:

测试组件

@Singleton
@Component(modules = {
        AndroidSupportInjectionModule.class,
        TestPersistenceModule.class
})
public interface TestComponent extends AndroidInjector<TestApplication> {

    @Component.Builder
    abstract class Builder extends AndroidInjector.Builder<TestApplication> {
    }
}

TestPersistenceModule

@Module(includes = TestRoomModule.class)
public abstract class TestPersistenceModule {

    @Binds
    abstract AssetRepository bindAssetRepository(final AssetRepositoryImpl repository);
}

TestRoomModule

@Module
public class TestRoomModule {

    @Provides
    @Singleton
    TestDatabase provideTestDatabase(final Application application) {
        return Room.inMemoryDatabaseBuilder(application, TestDatabase.class).build();
    }

    @Provides
    @Singleton
    AssetDao provideAssetDao(final TestDatabase testDatabase) {
        return testDatabase.getAssetDao();
    }
}

TestApplication

public class TestApplication extends DaggerApplication {

    @Override
    protected AndroidInjector<? extends DaggerApplication> applicationInjector() {
        return DaggerTestComponent.builder().create(this);
    }
}

除此之外,我还有一个自定义的AndroidJUnitRunner 扩展类,它覆盖newApplication 方法并为测试用例返回一个TestApplication 实例。

我的AssetRepositoryImpl如下:

AssetRepositoryImpl

@Singleton
public class AssetRepositoryImpl extends AbstractRepository<Asset, AssetEntity> implements AssetRepository {

    @Inject
    protected WorkspaceDao workspaceDao;

    @Inject
    public AssetRepositoryImpl(final AssetDao dao, final AssetMapper mapper) {
        super(dao, mapper);
    }
}

我没有在此处粘贴的类在其构造函数中具有 @Inject 注释,并且此代码在具有相应主要模块和组件的主应用程序中正常工作。

作为最后的想法,由 JUnit 实例化的 AssetRepositoryTest.PopulatedDatabaseInstace 因此没有被 Dagger 实例化,据我所知,这似乎是这里的问题。

如何告诉 Dagger 如何将这些字段注入到我的 JUnit 测试类中?

【问题讨论】:

    标签: java android dagger-2 instrumented-test


    【解决方案1】:

    您的匕首设置中似乎缺少一些步骤,我已经包含了一个我使用的清单。

    • 创建 CustomTestRunner
    class MyCustomTestRunner : AndroidJUnitRunner() {
    
        override fun newApplication(cl: ClassLoader?, name: String?, context: Context?): Application {
            return super.newApplication(cl, MyTestApplication::class.java.name, context)
        }
    }
    
    
    • 将测试运行器添加到 app/build.gradle
    android {
        ...
        defaultConfig {
            ...
            testInstrumentationRunner "com.example.android.dagger.MyCustomTestRunner"
        }
        ...
    }
    
    • kapt 需要作用于 AndroidTest 源集。
    ...
    dependencies {
        ...
        kaptAndroidTest "com.google.dagger:dagger-compiler:$dagger_version"
    }
    
    
    • 创建测试模块
    • 创建 TestAppComponent。
    • 主应用程序应如下所示
    open class MyApplication : Application() {
    
        val appComponent: AppComponent by lazy {
            initializeComponent()
        }
    
        open fun initializeComponent(): AppComponent {
            return DaggerAppComponent.factory().create(applicationContext)
        }
    }
    
    • 测试应用程序
    class MyTestApplication : MyApplication() {
    
        override fun initializeComponent(): AppComponent {
            // Creates a new TestAppComponent that injects fakes types
            return DaggerTestAppComponent.create()
        }
    }
    

    如果您正在寻找有关每个步骤的更多详细信息,您可以找到该信息here

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-05-20
      • 2022-01-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-03-17
      相关资源
      最近更新 更多