[英]Mock static java methods using Mockk
我们目前正在使用 java 和 kotlin 项目,慢慢将整个代码迁移到后者。
是否可以使用 Mockk 模拟像Uri.parse()
这样的 static 方法?
示例代码会是什么样子?
除了 oleksiyp 回答:
你必须使用unmockStatic()
。 如果自动取消模拟对您不起作用,请阅读另一个答案。
Mockk 版本 1.8.1 弃用了以下解决方案。 在该版本之后,您应该执行以下操作:
@Before
fun mockAllUriInteractions() {
mockkStatic(Uri::class)
every { Uri.parse("http://test/path") } returns Uri("http", "test", "path")
}
mockkStatic
每次调用都会被清除,所以你不再需要 unmock 了
已弃用:
如果您需要模拟行为始终存在,不仅在单个测试用例中,您可以使用@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
污染您的代码。
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
如果您在没有块的情况下调用mockkSatic()
,请不要忘记在调用模拟方法后调用unmockkStatic()
。 该方法不会自动取消模拟,即使在不调用mockkStatic()
而是使用静态方法的不同测试类中,您仍将获得模拟值。
另一种选择是在块内执行模拟方法,然后它将自动取消模拟:
mockkStatic(Uri::class) {
every { Uri.parse("http://test/path") } returns Uri("http", "test", "path")
val uri = Uri.parse("http://test/path")
}
除了接受的答案:
你不能像那样创建一个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>()
}
如果我们要模拟静态,例如: mockkStatic(Klass::class)
那么我们肯定要取消模拟它,例如: unmockkStatic(Klass::class)
我建议在 @After 注释的方法中取消模拟它。
一个完整的例子是:
class SomeTest {
private late var viewMode: SomeViewModel
@Before
fun setUp() {
viewMode = SomeViewModel()
mockkStatic(OurClassWithStaticMethods::class)
}
@After
fun tearDown() {
unmockkStatic(OurClassWithStaticMethods::class)
}
@Test
fun `Check that static method get() in the class OurClassWithStaticMethods was called`() {
//Given
every { OurClassWithStaticMethods.get<Any>(any()) } returns "dummyString"
//When
viewModel.doSomethingWhereStaticMethodIsCalled()
//Then
verify(exactly = 1) {
OurClassWithStaticMethods.get<Any>(any())
}
}
}
本示例使用模拟库“ Mockk ”v.1.12.0 编写
正如上面多个答案中提到的,您必须确保调用 unmockkStatic - 否则您最终会得到不稳定的测试(因为模拟对象/函数将在测试类中可用。
在我的场景中 - 我在 kotlin 中有一个模块范围的扩展 function 并模拟我使用了配套的 object ,如下所示:
class SampleTest {
companion object {
@BeforeAll
@JvmStatic
fun setup() {
mockkStatic("packagename.filenameKt")
}
@AfterAll
@JvmStatic
fun teardown() {
unmockkStatic("packagename.filenameKt")
}
}}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.