spring-boot - Kotlin : unit test with mock injection (mockK)

标签 spring-boot kotlin junit mockk

我按照许多博客的分步说明使用 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)
    }

}

我要注入(inject)externalApi进入我的SWService服务和模拟get注入(inject)对象( externalApi )的方法,但似乎忽略了模拟。

日志:
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()
    }

我的实现有问题吗?
谢谢

最佳答案

Kotlin 为 companion object {} 生成内部类调用Companion .这个Companion类将只有声明的字段的 setter/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 field 。这可以使用 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);
    }
}

希望能帮助到你。

关于spring-boot - Kotlin : unit test with mock injection (mockK),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57176433/

相关文章:

testing - neo4j 的测试数据

java - 将单元测试引入现有项目

java - Spring Security 出现 403 错误

java - 我的数据源设置有什么问题让 Spring Boot 连接到 MySQL?

reflection - 我想检测一个 JVM 类是否是 Kotlin 类

generics - Kotlin 接口(interface)函数可互换参数

java - 如何简化测试?

java - spring中如何根据profile调用一个bean的不同实现

java - 重新打包 Spring Boot 应用程序

kotlin - 数据类中的默认参数未使用 ktor 序列化程序转换为 json