我们目前正在使用带有kotlin项目的java,慢慢地将整个代码迁移到后者。
是否可以使用Mockk模拟静态方法,例如Uri.parse()
?
示例代码如何?
答案 0 :(得分:11)
除了oleksiyp答案:
Mockk版本1.8.1弃用了以下解决方案。在那个版本之后你应该这样做:
@Before
fun mockAllUriInteractions() {
mockkStatic(Uri::class)
every { Uri.parse("http://test/path") } returns Uri("http", "test", "path")
}
每次调用 mockkStatic
时都会被清除,所以你不需要再取消它了
<强>弃用:强>
如果您需要始终存在该模拟行为,不仅在单个测试用例中,您可以使用@Before
和@After
进行模拟:
@Before
fun mockAllUriInteractions() {
staticMockk<Uri>().mock()
every { Uri.parse("http://test/path") } returns Uri("http", "test", "path") //This line can also be in any @Test case
}
@After
fun unmockAllUriInteractions() {
staticMockk<Uri>().unmock()
}
这样,如果您希望您的课程中有更多部分使用Uri课程,您可以在一个地方进行模拟,而不是在任何地方使用.use
来污染您的代码。
答案 1 :(得分:7)
MockK允许模拟静态Java方法。它的主要目的是模拟Kotlin扩展函数,因此它不如PowerMock强大,但即使对于Java静态方法,它仍然可以完成它。
语法如下:
staticMockk<Uri>().use {
every { Uri.parse("http://test/path") } returns Uri("http", "test", "path")
assertEquals(Uri("http", "test", "path"), Uri.parse("http://test/path"))
verify { Uri.parse("http://test/path") }
}
答案 2 :(得分:6)
如果您在没有块的情况下调用 mockkSatic()
,请不要忘记在调用模拟方法后调用 unmockkStatic()
。该方法不会自动解除模拟,即使在不调用 mockkStatic()
而是使用静态方法的不同测试类中,您仍然会获得模拟值。
另一种选择是在块内执行模拟方法,然后它会自动解除模拟:
mockkStatic(Uri::class) {
every { Uri.parse("http://test/path") } returns Uri("http", "test", "path")
val uri = Uri.parse("http://test/path")
}
答案 3 :(得分:1)
除了已接受的答案:
您不能像这样创建Uri
,也必须模拟Uri实例。像这样:
private val mockUri = mockk<Uri>()
@Before
fun mockAllUriInteractions() {
mockkStatic(Uri::class)
every { Uri.parse("http://test/path") } returns mockUri
// or just every { Uri.parse("http://test/path") } returns mockk<Uri>()
}