android-fragments 如何使用视图模型工厂注入片段以在Android中进行插装测试

wrrgggsh  于 2022-11-14  发布在  Android
关注(0)|答案(1)|浏览(157)

我有下面的Dagger组件设置,它很适合我的应用程序。

@Singleton
@Component(
    modules = [
        ApiModule::class,
        DatabaseModule::class,
        ViewModelModule::class,
        ActivityModule::class,
        AndroidSupportInjectionModule::class
    ]
)
interface AppComponent : AndroidInjector<App> {
    @Component.Builder
    interface Builder {
        @BindsInstance
        fun application(app: Application): Builder

        fun build(): AppComponent
    }
}

我希望为ApiModule(Retrofit mock)和DatabaseModule(InMemory Room DB)提供一个自定义实现,以便进行仪器测试。因此,我创建了一个测试组件,如下所示:

@Singleton
@Component(
    modules = [
        MockApiModule::class,
        TestDatabaseModule::class,
        ViewModelModule::class,
        ActivityModule::class,
        AndroidSupportInjectionModule::class
    ]
)
interface TestComponent : AndroidInjector<App> {
    @Component.Builder
    interface Builder {
        fun build(): TestComponent
    }
}

我的片段需要注入ViewModelProvider.Factory

class MovieListingFragment : BaseFragment() {
    @Inject lateinit var factory: ViewModelProvider.Factory
    private val vm: MovieViewModel by navGraphViewModels(R.id.mobile_navigation) { factory }

我使用ViewModelModule生成的代码如下所示:

@Module
interface ViewModelModule {
    @Binds
    @IntoMap
    @ViewModelKey(MovieViewModel::class)
    fun bindMovieViewModel(vm: MovieViewModel): ViewModel

    @Binds
    fun bindViewModelFactory(factory: ViewModelFactory): ViewModelProvider.Factory
}

如何在测试片段中注入此内容?

@RunWith(AndroidJUnit4::class)
class MovieListFragmentTest {
    @Test
    fun testMovieListFragment() {
        val scenario = launchFragmentInContainer<MovieListingFragment>()
        scenario.moveToState(Lifecycle.State.RESUMED)
    }
}
ruarlubt

ruarlubt1#

有很多方法可以实现这一点,但最适合我的方法是创建一个特殊的mock buildType,该buildType具有不同的依赖注入设置,用于我不想使用“真实的”的API。然后,我的UI测试将在src/androidTestMock下运行,以便它运行mock buildType。
您还必须:
1.连接您的API,以便为您的构建类型提供模拟或真实的实现
1.不是在主源代码中而是在每个构建类型中实现非模拟DI设置(例如调试、发布)。这只适用于在您的mock构建类型中需要特殊版本的API。在所有构建类型中“真实的存在”的模块将进入您的主源代码。这将导致一些代码重复,如果您真的想这样做,您可以通过使用非模拟源代码集来避免。
1.请确保您的模拟类是作为单例提供的,否则您的测试(将执行模拟或不同的测试设置)将收到与您的应用不同的示例。
1.确保CI/CD也是您的模拟构建类型,因为您将主要处理其他构建类型,并且您希望尽早捕获中断的编译。
在您的示例中,TestComponent位于src/mock中,AppComponent位于src/debug和src/release中。

相关问题