kotlin:模拟注入的单元测试(mockK)

时间:2019-07-24 06:20:14

标签: 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)
    }

}

我想将externalApi注入我的SWService服务中,并模拟注入对象(get)的externalApi方法,但似乎忽略了该模拟。 / p>

日志:

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()
    }

我的实现中有问题吗? 谢谢

1 个答案:

答案 0 :(得分:0)

Kotlin为companion object {}生成了一个内部类,称为Companion。这个Companion类只能为声明的字段(在您的情况下为getApi()中)使用getter。但是该字段由外部类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);
    }
}

希望有帮助。