Android-为每个测试使用注入到活动中的不同模拟对象

时间:2018-10-02 07:25:13

标签: android kotlin rx-java2 android-testing

我有一个SplashActivity,它在用户登录状态(继续进行家庭或登录活动)时的行为应有所不同

我正在使用Dagger2ViewModel注入Activity,并将Repository注入ViewModel

@Module 
abstract class ActivityBindingModule {

    @ContributesAndroidInjector
    abstract fun splashActivity(): SplashActivity

}

和:

class SplashViewModel @Inject constructor(
        private val usersRepository: UsersRepository
) : BaseViewModel<SplashState>(SplashState.LOADING) {

    private var isInit = false

    fun init() {
        if (isInit) return
        isInit = true

        addDisposable(usersRepository
                .isUserLogin()
                .subscribe({
                    state.value = if (it)
                        SplashState.CONTINUE_LOGIN_USER
                    else
                        SplashState.CONTINUE_NOT_LOGIN_USER

                    isInit = false
                }, {
                    message.value = it.message
                    state.value = SplashState.ERROR

                    isInit = false
                }))
    }
}

我想实现一个Android自动测试来根据场景检查SplashActivity的反应。因此,我创建了一个在测试中模拟我的存储库的模块:

@Module
class TestApplicationModule {
    @Provides
    fun provideUserRepository(): UsersRepository = mock(UsersRepository::class.java).apply { 
        `when`(isUserLogin()).then { /* it should return true or false depending on the running test */ }
    }
}

如何根据正在运行的测试将模拟的Repository对象的不同实例传递到ViewModel来实现我的测试,如下所示:

@RunWith(AndroidJUnit4::class)
@LargeTest
class SplashActivityTest {

    // ...

    @Test
    fun notLoginUserNavigateToLogin() {
        // Change mocked function behavior
        // ...
        Intents.intended(IntentMatchers.hasComponent(LoginActivity::class.java.name))
    }

    @Test
    fun loginUserNavigateToHome() {
        // Change mocked function behavior
        // ...
        Intents.intended(IntentMatchers.hasComponent(HomeActivity::class.java.name))
    }
}

注意:我想到的一个解决方案是使用全局object并更改变量值以更改模拟函数的行为,但我认为应该有更好的做法。

0 个答案:

没有答案