Android 架构组件 ViewModel - 如何在测试 Activity 上模拟 ViewModel? [英] Android Architecture Component ViewModel - How to mock ViewModel on test Activity?

查看:33
本文介绍了Android 架构组件 ViewModel - 如何在测试 Activity 上模拟 ViewModel?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试设置类似于 GithubBrowserSample 的 UI 测试,看起来示例项目只有 Fragment 的模拟 ViewModel 但没有Activity 的示例.

这是我尝试通过模拟 ViewModel 来测试 Activity 的代码.但是 ViewModel 没有在 Activity 中的 onCreate() 之前设置.

@RunWith(AndroidJUnit4::class)类 MainActivityTest {val viewModel = 模拟(MainViewModel::class.java)@规则@JvmFieldval activityRule = ActivityTestRule(MainActivity::class.java, true, true)private val liveData = MutableLiveData>()@前打开乐趣设置(){activityRule.activity.viewModelFactory = createViewModelFor(viewModel)`when`(viewModel.liveData).thenReturn(liveData)viewModel.liveData?.observeForever(mock(Observer::class.java) as Observer>)liveData.postValue(Resource.success(Object()))}有趣的<T:ViewModel>createViewModelFor(model: T): ViewModelProvider.Factory =对象:ViewModelProvider.Factory {覆盖乐趣 <T : ViewModel>创建(模型类:类):T{如果(modelClass.isAssignableFrom(model.javaClass)){返回模型为 T}throw IllegalArgumentException("意外的模型类" + modelClass)}}}

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

解决方案

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

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

I'm trying to setup UI testing similar to GithubBrowserSample and it looks like the sample project only has mock ViewModel for Fragment but not an example for Activity.

Here's my code where I am trying to test the Activity by mocking ViewModel. But the ViewModel is not getting set before onCreate() in Activity.

@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)
            }
        }
}

Can someone help me about this issue please?

解决方案

JUnit @Rules do their setup before @Before methods, so your activity is launching and starting its lifecycle before your setUp() method gets called. To avoid this, pass false as the third parameter to the rule constructor. This tells it not to launch the activity automatically, so you can do your setup in advance.

Then, you need to launch the activity manually before you run your tests. You can create an intent like val intent = Intent(InstrumentationRegistry.targetContext, MainActivity::class.java) and then pass it to activityRule.launchActivity(intent).

这篇关于Android 架构组件 ViewModel - 如何在测试 Activity 上模拟 ViewModel?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆