kotlin:模拟注入的单元测试(mockK)
Posted
技术标签:
【中文标题】kotlin:模拟注入的单元测试(mockK)【英文标题】:kotlin : unit test with mock injection (mockK) 【发布时间】:2019-12-02 05:23:36 【问题描述】:我按照许多博客的分步说明使用 MockK 实现模拟:
class SWServiceImplTest
@MockK
lateinit var externalApi: ExternalApiService
@InjectMockKs
lateinit var SWService: SWServiceImpl
@Before
fun setUp() = MockKAnnotations.init(this)
@Test
fun SWCharacterReturnsCorrectValues()
every externalApi.get<Characters>(Utils.SW_API) returns mockCharacters()
val result = SWService.swCharacter!!
assertEquals("blue", result.first().color?.toLowerCase())
assertEquals(result.size, 3)
我想将externalApi
注入我的SWService
服务并模拟注入对象(externalApi
)的get
方法,但似乎忽略了模拟。
日志:
15:09:54.497 [main] DEBUG io.mockk.impl.instantiation.AbstractMockFactory - Creating mockk for <error "java.lang.NoClassDefFoundError: kotlin/coroutines/intrinsics/IntrinsicsKt"> name=externalApi#1
15:09:56.820 [main] DEBUG org.springframework.web.client.RestTemplate - HTTP GET https://xxx.xxx/
15:09:57.038 [main] DEBUG org.springframework.web.client.RestTemplate - Accept=[application/json, application/*+json]
org.springframework.web.client.RestClientException: No HttpMessageConverter for java.lang.Object and content type ""
在我的SWService
文件中,externalApi
在伴随对象中被初始化:
companion object
val api = ExternalApiService()
我的实现有问题吗? 谢谢
【问题讨论】:
你是如何在SWService
类中初始化externalApi
的?你能把那个代码也贴一下吗?
感谢@SuryavelTR 的评论。我更新了我的消息:它在我的类中的伴随对象中初始化
删除了一条评论。错过了关于 InjectMocks SWService 的要点。所以。您无法将 InjectMocks 注入伴随对象。我建议在构造函数中使用 api
类似的 lateinit var
作为字段或 val
(相信这个也可以)
这能回答你的问题吗? How to mock a Kotlin singleton object?
【参考方案1】:
Kotlin 为 companion object
生成一个名为 Companion
的内部类。这个Companion
类将只有声明的字段的getter(在您的情况下为getApi()
)。但该字段由外部类SWService
维护。
所以 SWService 的等效 java 类看起来像。
public final class SWService
private static final ExternalApiService api = new ExternalApiService();
public static final class Companion()
public final ExternalApiService getApi()
return SWService.api;
现在您要模拟 api
即 static
字段。这可以使用powermockito
来完成。
添加这个依赖,
testImplementation "org.powermock:powermock-api-mockito2:2.0.0-beta.5"
在你的测试中,
public final class SWServiceTest
@MockK
lateinit var api: ExternalApiService
var service = SWService()
@Before
fun setUp()
MockKAnnotations.init(this)
Whitebox.setInternalState(SWService::class.java,"api", api);
希望对你有帮助。
【讨论】:
感谢您的回复。我尝试使用powermock
实现,但我仍然遇到同样的错误...(为 以上是关于kotlin:模拟注入的单元测试(mockK)的主要内容,如果未能解决你的问题,请参考以下文章
使用 Kotlin 数据类的 Json 解析器正确返回 json 数据,但是为啥解析器(MockK)的单元测试会失败?
安卓Kotlin单元测试/ Collection, ArrayList依赖的解耦/ MockK
Kotlin Spring Boot 单元测试 - 添加 @TestExecutionListeners 不会注入依赖项