【发布时间】:2022-01-05 05:42:09
【问题描述】:
我正在使用 Hilt 开发应用程序,一切正常,但是当我尝试在运行低于 Android P 的设备上运行一些 Espresso 测试时,我遇到了问题。
当我尝试模拟(使用 Mockk)ViewModel 以便我可以对我的 Fragment 进行单元测试时,问题就出现了。当 Fragment 尝试实例化 ViewModel 时,我在创建 ViewModel 时收到 NullPointerException。 NPE 被抛出方法setTagIfAbsent。问题是这个方法是包私有的,你可以在ViewModel source code上看到,所以它不能在Android上模拟
我尝试过使用Kotlin All-Open plugin,它有助于模拟 ViewModel 并将其存入公共方法。我尝试使用 mockk 私有存根来存根 setTagIfAbsent,如下所示:
every{
myViewModelMock["setTagIfAbsent"](any<String>,any())
} answers {secondArg()}
但是当setTagIfAbsent被调用时,真正的方法被调用,抛出NPE,因为ViewModel.mBagOfTags为空,因为类是一个模拟。
其余代码如下:
视图模型:
@OpenForTesting
@HiltViewModel
class MyViewModel @Inject constructor MyViewModel(private val dependency: Dependency): ViewModel(){
//Rest of the code
}
片段:
@AndroidEntryPoint
class MyFragment: Fragment(){
private val viewModel: MyViewModel by viewModels()
//Rest of the code
}
测试类:
@HiltAndroidTest
@RunWith(AndroidJUnit4::class)
class MyFragmentTest {
@Bind
@MockK
lateinit var viewModel: MyViewModel
@get:Rule
var hiltRule = HiltAndroidRule(this)
@Before
fun prepareTest(){
MockkAnnotations.init(this)
hiltRule.inject()
launchFragmentInHiltContainer<MyFragment>()
}
@Test
fun testThatWillMakeAViewModelInvokation(){
onView(withId(R.id.button)).perform(click())
//Assume that button will make the ViewModel be called and created by the delegate
//When this happens the NPE is thrown
}
}
方法launchFragmentInHiltContainer来自here (Hilt sample app)。
如果你看Mockk Android documentation,据说 有没有人知道我该如何解决这个问题或如何修复测试? 提前致谢。
【问题讨论】:
标签: android kotlin dagger-hilt mockk