Dan*_*der 2 java android dagger-2 instrumented-test
我正在尝试在 Android 仪器测试中使用 Dagger 2 进行 DI。它对于主应用程序组件中的类/活动/片段工作得很好,但我的测试组件似乎缺少一些我找不到的绑定。任何有关如何进行的想法将不胜感激。我的代码如下所示:
资产库测试
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
}
}
Run Code Online (Sandbox Code Playgroud)
运行仪器测试时出现以下异常:
java.lang.IllegalArgumentException: No injector factory bound for Class<AssetRepositoryTest.PopulatedDatabaseInstance>
Run Code Online (Sandbox Code Playgroud)
与匕首相关的代码如下:
测试组件
@Singleton
@Component(modules = {
AndroidSupportInjectionModule.class,
TestPersistenceModule.class
})
public interface TestComponent extends AndroidInjector<TestApplication> {
@Component.Builder
abstract class Builder extends AndroidInjector.Builder<TestApplication> {
}
}
Run Code Online (Sandbox Code Playgroud)
测试持久性模块
@Module(includes = TestRoomModule.class)
public abstract class TestPersistenceModule {
@Binds
abstract AssetRepository bindAssetRepository(final AssetRepositoryImpl repository);
}
Run Code Online (Sandbox Code Playgroud)
测试室模块
@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();
}
}
Run Code Online (Sandbox Code Playgroud)
测试应用
public class TestApplication extends DaggerApplication {
@Override
protected AndroidInjector<? extends DaggerApplication> applicationInjector() {
return DaggerTestComponent.builder().create(this);
}
}
Run Code Online (Sandbox Code Playgroud)
除此之外,我有一个自定义AndroidJUnitRunner扩展类,它重写该newApplication方法并返回TestApplication测试用例的实例。
我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);
}
}
Run Code Online (Sandbox Code Playgroud)
我未在此处粘贴的类@Inject在其构造函数中具有注释,并且此代码在具有相应主模块和组件的主应用程序中正常工作。
As a final thought, the AssetRepositoryTest.PopulatedDatabaseInstace, which is instantiated by JUnit, is therefore not instantiated by Dagger and, to my knowledge, that seems to be the problem here.
How can I tell Dagger how to inject these fields into my JUnit test class?
似乎您在匕首设置中缺少一些步骤,我已经提供了我使用的清单。
class MyCustomTestRunner : AndroidJUnitRunner() {
override fun newApplication(cl: ClassLoader?, name: String?, context: Context?): Application {
return super.newApplication(cl, MyTestApplication::class.java.name, context)
}
}
Run Code Online (Sandbox Code Playgroud)
android {
...
defaultConfig {
...
testInstrumentationRunner "com.example.android.dagger.MyCustomTestRunner"
}
...
}
Run Code Online (Sandbox Code Playgroud)
...
dependencies {
...
kaptAndroidTest "com.google.dagger:dagger-compiler:$dagger_version"
}
Run Code Online (Sandbox Code Playgroud)
open class MyApplication : Application() {
val appComponent: AppComponent by lazy {
initializeComponent()
}
open fun initializeComponent(): AppComponent {
return DaggerAppComponent.factory().create(applicationContext)
}
}
Run Code Online (Sandbox Code Playgroud)
class MyTestApplication : MyApplication() {
override fun initializeComponent(): AppComponent {
// Creates a new TestAppComponent that injects fakes types
return DaggerTestAppComponent.create()
}
}
Run Code Online (Sandbox Code Playgroud)
如果您正在寻找有关每个步骤的更多详细信息,您可以在此处找到该信息。
| 归档时间: |
|
| 查看次数: |
1137 次 |
| 最近记录: |