Android架构组件ViewModel - 如何在测试Activity上模拟ViewModel?

Nux*_*Nux 8 android kotlin android-espresso android-viewmodel android-architecture-components

我想类似的设置UI测试GithubBrowserSample,它看起来像示例项目只有模仿ViewModelFragment,但不是一个例子Activity.

这是我的代码,我试图Activity通过嘲笑来测试ViewModel.但是在Activity ViewModel之前没有设置好onCreate().

@RunWith(AndroidJUnit4::class)
class MainActivityTest {

    val viewModel = mock(MainViewModel::class.java)

    @Rule
    @JvmField
    val activityRule = ActivityTestRule<MainActivity>(MainActivity::class.java, true, true)

    private val liveData = MutableLiveData<Resource<Object>>()

    @Before
    open fun setUp() {
        activityRule.activity.viewModelFactory = createViewModelFor(viewModel)
        `when`(viewModel.liveData).thenReturn(liveData)
        viewModel.liveData?.observeForever(mock(Observer::class.java) as Observer<Resource<Object>>)
        liveData.postValue(Resource.success(Object()))
    }

    fun <T : ViewModel> createViewModelFor(model: T): ViewModelProvider.Factory =
        object : ViewModelProvider.Factory {
            override fun <T : ViewModel> create(modelClass: Class<T>): T {
                if (modelClass.isAssignableFrom(model.javaClass)) {
                    return model as T
                }
                throw IllegalArgumentException("unexpected model class " + modelClass)
            }
        }
}
Run Code Online (Sandbox Code Playgroud)

有人可以帮我解决这个问题吗?

Bru*_*let 3

JUnit在方法@Rule之前进行设置,因此您的活动在调用方法@Before之前启动并开始其生命周期。setUp()为了避免这种情况,请将false第三个参数传递给规则构造函数。这告诉它不要自动启动该活动,因此您可以提前进行设置。

然后,您需要在运行测试之前手动启动该活动。您可以创建一个意图val intent = Intent(InstrumentationRegistry.targetContext, MainActivity::class.java),然后将其传递给activityRule.launchActivity(intent).