使用activityViewModels测试Android片段

5

我正在尝试为共享同一ViewModel的片段运行Android仪器测试。 ViewModel具有一些参数。 我使用koin,但在测试中使用activityViewModels时,koin不会注入ViewModel。

class SomeFragment() : Fragment() {
    private val viewModel: SomeViewModel by activityViewModels()
    ... more code
}

class SomeFragmentTest() : KoinTest{

    @Before
    fun setup() {
        val viewModel: SomeViewModel = mockk(relaxed = true)

        startKoin { loadKoinModules(listOf(
            module(override = true) { viewModel },
            module(override = true) { factory { appAnalytics } })) }
    }
.... more code
}

收到的消息是:
Caused by: java.lang.InstantiationException: java.lang.Class<SomeViewModel> has no zero argument constructor

1
你应该标记自己的答案 :) 这仍然是一个在2021年11月仍然有效的好解决方案。 - Martin Marconcini
1个回答

8
我找到了解决方案,并发布了这个问题,希望能帮助到其他人。
我在片段中添加了一个视图模型工厂:
class SomeFragment(val factory: (() -> ViewModelProvider.Factory)? = null) : Fragment() {
    private val viewModel: SomeViewModel by activityViewModels(factory)
    ... more code
}

class SomeFragmentTest() : KoinTest{
    private val fragmentFactory : FragmentFactory = mockk() 
    
    @Before
    fun setup() {
        val viewModel: SomeViewModel = mockk(relaxed = true)
        ... some mock related to viewModel
        val viewModelFactory : ViewModelProvider.Factory = mockk()
        every { viewModelFactory.create(SomeViewModel::class.java) } answers { viewModel }
        every { fragmentFactory.instantiate(any(), any()) } answers { SomeFragment{
            viewModelFactory
        }}
    }
    @Test
    fun test_fragment() {
        launchFragmentInContainer<SomeFragment>(
            themeResId = R.style.AppTheme,
            factory = fragmentFactory
        )
        ... some asserts 
    }

.... more code
}

这在生产环境下可行,因为在activityViewModels实现中,当工厂为空时会使用默认值:

inline fun <reified VM : ViewModel> Fragment.activityViewModels(
    noinline factoryProducer: (() -> Factory)? = null
) = createViewModelLazy(VM::class, { requireActivity().viewModelStore },
    factoryProducer ?: { requireActivity().defaultViewModelProviderFactory })

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接