ona*_*per 5 testing android unit-testing
我正在尝试对共享相同 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
}
Run Code Online (Sandbox Code Playgroud)
收到的消息是
Caused by: java.lang.InstantiationException: java.lang.Class<SomeViewModel> has no zero argument constructor
Run Code Online (Sandbox Code Playgroud)
我找到了解决方案,并发布了这个问题,希望对其他人有帮助。
我将一个视图模型工厂添加到片段中:
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
}
Run Code Online (Sandbox Code Playgroud)
这适用于 prod,因为在 ActivityViewModels 实现中,当工厂为 null 时,将使用默认值:
inline fun <reified VM : ViewModel> Fragment.activityViewModels(
noinline factoryProducer: (() -> Factory)? = null
) = createViewModelLazy(VM::class, { requireActivity().viewModelStore },
factoryProducer ?: { requireActivity().defaultViewModelProviderFactory })
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1078 次 |
| 最近记录: |