手柄视图模型注入到仪器测试中 [英] Hilt viewmodel injection into instrumentation tests

查看:0
本文介绍了手柄视图模型注入到仪器测试中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在搜索如何将ViewModel注入测试中,以便我可以对其进行测试。假设视图模型有一个带有某个业务逻辑交互程序的构造函数注入。我可以很容易地将它注射到碎片中,但在测试中没有成功。

@HiltAndroidTest
class ViewModelTest

 val randomViewmodel: RandomViewmodel// now what ? since by viewModels() is not accessible in tests

    @Test
    fun viewModelTet() {
        randomViewmodel.triggerAction()
        assertEquals(RandomVIewState(1), randomViewmodel.getState())
    }

我尝试在测试类中实现byViewModels(),可以在没有构造函数参数的情况下注入视图模型,但没有成功。

class RandomViewmodel @ViewModelInject constructor(
     private val randomInteractor: RandomInteractor
) : ViewModel
Caused by: java.lang.InstantiationException: class app.RandomViewModel has no zero argument constructor

原因:我希望能够完全测试我的屏幕逻辑,因为viewModel将处理交互因素等的依赖关系,可能会有相当多的逻辑与各种数据流动在一起。测试片段很可能是可能的,但在包含大量测试的较大对象中要慢得多。

我已经读过https://developer.android.com/jetpack/guide#test-components,它建议在viewModel中进行JUnit测试和模拟依赖项,但然后您必须分别为每个依赖项创建测试,无法真正测试整个屏幕的逻辑

推荐答案

@HiltViewModel批注生成您原本应该编写的绑定模块。

其中之一是名为BindsModule的模块。 此类在包含该多绑定模块和一个键的包装类中声明。

例如,假设您创建了一个名为MyViewModel的ViewModel

package com.mypackage

@HiltViewModel
class MyViewModel @Inject constructor(
    private val someDependency: MyType
) : ViewModel()

则生成的模块如下所示:

@OriginatingElement(
    topLevelClass = MyViewModel.class
)
public final class MyViewModel_HiltModules {
  private MyViewModel_HiltModules() {
  }

  @Module
  @InstallIn(ViewModelComponent.class)
  public abstract static class BindsModule {
    private BindsModule() {
    }

    @Binds
    @IntoMap
    @StringKey("com.mypackage.MyViewModel")
    @HiltViewModelMap
    public abstract ViewModel binds(MyViewModel vm);
  }

  @Module
  @InstallIn(ActivityRetainedComponent.class)
  public static final class KeyModule {
    private KeyModule() {
    }

    @Provides
    @IntoSet
    @HiltViewModelMap.KeySet
    public static String provide() {
      return "com.mypackage.MyViewModel";
    }
  }
}

因此,您ViewModel可以替换@Binds约定,只需在测试类中与实现类型匹配的属性上使用@BindValue注释,在本例中,它将是MyViewModel

无需卸载与ViewModel相关的任何模块。

@HiltAndroidTest
class MyFragmentInstrumentedUnitTest {
    @get:Rule val hiltRule = HiltAndroidRule(this)

    // either a subclass or a mock, as long as the types match
    // it will provide this instance as the implementation of the abstract binding 
    // `public abstract ViewModel binds(MyViewModel vm);`
    @BindValue
    val mockMyViewModel= mock<MyViewModel>()

    @Before
    fun init() {
        hiltRule.inject()
    }
}

这篇关于手柄视图模型注入到仪器测试中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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