使用Mockk模拟静态java方法

时间:2018-04-10 20:31:35

标签: java unit-testing static kotlin mockk

我们目前正在使用带有kotlin项目的java,慢慢地将整个代码迁移到后者。

是否可以使用Mockk模拟静态方法,例如Uri.parse()

示例代码如何?

4 个答案:

答案 0 :(得分:11)

除了oleksiyp答案:

在mockk 1.8.1之后:

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") }  
}

此处有更多详情:http://mockk.io/#extension-functions

答案 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>()
}