具有由 Hilt 在仪器测试零参数构造函数中注入的可组合项的真实 ViewModel

发布于 2025-01-11 22:00:56 字数 1372 浏览 0 评论 0原文

我想将真正的 ViewModel 注入到我的可组合项中。 这个问题的答案说明了如何模拟注入的视图模型,这不是我想要的。

我的可组合项正在接收如下视图模型:

fun YourDetailsS​​creen(viewModel: YourDetailsViewModel = viewModel()) {

viewModel() 方法是 提供的内联函数>androidx.lifecycle.viewmodel.compose 包。

据我所知,我已经实现了自定义测试运行程序,我的仪器测试已使用 @HiltAndroidTest 和包装我的 composeTestRule< 的 HiltAndroidRule 正确配置。 /code> 像这样:

@get:Rule
val rule: RuleChain = RuleChain.outerRule(hiltAndroidRule)
   .around(composeTestRule)

当我启动可组合项时,出现以下异常:

引起:java.lang.InstantiationException:java.lang.Class没有零参数构造函数

这是我的 ViewModel 的构造函数。

@HiltViewModel
class YourDetailsViewModel @Inject constructor(
    private val isFirstNameValidUseCase: IsFirstNameValidUseCase,
    private val isLastNameValidUseCase: IsLastNameValidUseCase,
    private val isPhoneNumberValidUseCase: IsPhoneNumberValidUseCase
) : ViewModel()

运行应用程序时,一切都注入得很好,我只是无法让它在我的 Android 测试中工作!

I want to have the real ViewModel injected into my composable. This question's answer is stating how to mock the injected view model which is not what I want.

My composable is receiving the view model like this:

fun YourDetailsScreen(viewModel: YourDetailsViewModel = viewModel()) {

The viewModel() method is the inline function provided by the androidx.lifecycle.viewmodel.compose package.

As far as I'm aware, I have implemented the custom test runner, my instrumentation test is configured correctly with the @HiltAndroidTest and the HiltAndroidRule wrapping my composeTestRule like so:

@get:Rule
val rule: RuleChain = RuleChain.outerRule(hiltAndroidRule)
   .around(composeTestRule)

When I launch my composable, I get the following exception:

Caused by: java.lang.InstantiationException: java.lang.Class<com.zzz.feature.onboarding.registration.yourdetails.YourDetailsViewModel> has no zero argument constructor

Here is my ViewModel's constructor.

@HiltViewModel
class YourDetailsViewModel @Inject constructor(
    private val isFirstNameValidUseCase: IsFirstNameValidUseCase,
    private val isLastNameValidUseCase: IsLastNameValidUseCase,
    private val isPhoneNumberValidUseCase: IsPhoneNumberValidUseCase
) : ViewModel()

Everything is injected fine when running the app, I just can't get it to work in my android tests!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

伴我老 2025-01-18 22:00:56

经过几个小时的调试,发现了问题。

基本上,主要问题是我使用 createComposeRule() 而不是 createAndroidComposeRule(),因此未使用 HiltViewModelFactory

当我开始使用 createAndroidComposeRule() 如下时,我的测试开始运行:(

@RunWith(AndroidJUnit4::class)
@HiltAndroidTest
class MyScreenTest  {

    val hiltRule = HiltAndroidRule(this)

    val composeTestRule = createAndroidComposeRule<MyActivity>()

    @get:Rule
    val rule: RuleChain = RuleChain.outerRule(hiltRule)
        .around(composeTestRule)

    // Tests....
}

MyActivity 必须用 @AndroidEntryPoint 注释)

After some hours of debugging, found the issue.

Basically, the main problem was that I was using createComposeRule() instead of createAndroidComposeRule<MyActivity>(), so the HiltViewModelFactory was not used.

After I started using createAndroidComposeRule<MyActivity>() as follow, my test started running:

@RunWith(AndroidJUnit4::class)
@HiltAndroidTest
class MyScreenTest  {

    val hiltRule = HiltAndroidRule(this)

    val composeTestRule = createAndroidComposeRule<MyActivity>()

    @get:Rule
    val rule: RuleChain = RuleChain.outerRule(hiltRule)
        .around(composeTestRule)

    // Tests....
}

(MyActivity must be annotated with @AndroidEntryPoint)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文