您好,登錄后才能下訂單哦!
今天就跟大家聊聊有關(guān)Mockito mock Kotlin Object類方法報(bào)錯(cuò)該如何解決,可能很多人都不太了解,為了讓大家更加了解,小編給大家總結(jié)了以下內(nèi)容,希望大家根據(jù)這篇文章可以有所收獲。
比如我創(chuàng)建一個(gè)Kotlin
Object
類:ObjectMethod
package com.baichuan.example.unit_test object ObjectMethod { fun doSomething() { println("this is ObjectMethod#doSomething") } @JvmStatic fun doSomethingWithJvmStatic() { println("this is ObjectMethod#doSomethingWithJvmStatic") } }
如果我直接去mock
該類的doSomething
方法,會報(bào)錯(cuò)。
@Test @DisplayName("mock普通的kotlin靜態(tài)方法") fun testMockKotlinObject() { Assertions.assertThrows(MissingMethodInvocationException::class.java) { Mockito.mockStatic(ObjectMethod::class.java).`when`<Unit>( ObjectMethod::doSomething ).thenAnswer { println("this is mocked Object#doSomething") } } ObjectMethod.doSomething() }
這是因?yàn)?code>kotlin里的object
類里的方法雖然在kotlin
里從形態(tài)跟使用上來看與靜態(tài)方法無二。但是編譯成java
代碼后,其本質(zhì)其實(shí)是內(nèi)部初始化了一個(gè)當(dāng)前類的靜態(tài)常量實(shí)例INSTANCE
。這個(gè)INSTANCE
在kotlin
語法里被隱藏了,但在java里依然可以顯示訪問。ObjectMethod
編譯成java
后的代碼如下:
public final class ObjectMethod { @NotNull public static final ObjectMethod INSTANCE = new ObjectMethod(); private ObjectMethod() { } public final void doSomething() { String var1 = "this is ObjectMethod#doSomething"; boolean var2 = false; System.out.println(var1); } @JvmStatic public static final void doSomethingWithJvmStatic() { String var0 = "this is ObjectMethod#doSomethingWithJvmStatic"; boolean var1 = false; System.out.println(var0); } }
所以,不能mock
ObjectMethod#doSomething
本質(zhì)上的原因是正常手段無法mock
靜態(tài)常量。如果想要使kotlin
的object
類中的方法能夠被mock
,只需在方法上加上@JvmStatic
注解即可。被其標(biāo)注的方法會被編譯成普通的java
靜態(tài)方法。
上面說正常手段無法mock靜態(tài)常量,那么非正常手段呢?其實(shí)這個(gè)非正常手段就是通過反射將被mock
過的實(shí)例注入到ObjectMethod
中即可。
@Test @DisplayName("通過反射修改靜態(tài)常量來mock普通的kotlin靜態(tài)方法") fun testMockKotlinObjectMethodByReflection() { val mock = Mockito.mock(ObjectMethod::class.java) Mockito.`when`(mock.doSomething()).then { print("this is mocked ObjectMethod by reflection") } val declaredMethod = ObjectMethod::class.java.getDeclaredField("INSTANCE") ReflectionUtils.setFinalStatic(declaredMethod, mock) ObjectMethod.doSomething() }
ReflectionUtils
package com.baichuan.example.unit_test import java.lang.reflect.Field import java.lang.reflect.Modifier object ReflectionUtils { @Throws(Exception::class) fun setFinalStatic(field: Field, newValue: Any) { field.isAccessible = true val modifiersField: Field = Field::class.java.getDeclaredField("modifiers") modifiersField.isAccessible = true modifiersField.setInt(field, field.modifiers and Modifier.FINAL.inv()) field.set(null, newValue) } }
看完上述內(nèi)容,你們對Mockito mock Kotlin Object類方法報(bào)錯(cuò)該如何解決有進(jìn)一步的了解嗎?如果還想了解更多知識或者相關(guān)內(nèi)容,請關(guān)注億速云行業(yè)資訊頻道,感謝大家的支持。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。