【问题标题】:kotlin : unit test with mock injection (mockK)kotlin:模拟注入的单元测试(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?

标签: spring-boot kotlin junit mockk


【解决方案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;
       }
   }
}

现在您要模拟 apistatic 字段。这可以使用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 实现,但我仍然遇到同样的错误...(为
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-01-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多