Spring Boot + Kotlinでmockitoを使ってモック化したテストコードを書く
今回はkotlinでmockito使って処理をモック化したテストコードを書いてみた。
セットアップ
dependencies { ... testCompile "org.springframework.boot:spring-boot-starter-test" testCompile "org.mockito:mockito-core:$mockito_core_version" testCompile 'junit:junit:$junit_version' }
※ mockitoは1.10.19を使いました。
モック化するクラス
- Elasticsearchからデータを取得するサービスクラスを想定してモック化します。
- 今回はモック化メインなのでElasticsearch側の処理は適当です。
interface ElasticsearchClient { fun foo() : String } @Service class ElasticsearchClientImpl : ElasticsearchClient { override fun foo() : String { return "foo" } }
- foo()メソッドは"foo"を返すように実装しています。
- このfoo()メソッドをコントローラーから呼び出し、コントローラーのテストでfoo()メソッドをモック化します。
テスト対象のコントローラー
@RestController @EnableAutoConfiguration @ComponentScan @Api(description = "ヘルスチェック") open class HealthCheckController constructor(val elasticsearchClient: ElasticsearchClient) { @ApiModel data class HealthCheck( @ApiModelProperty(required = true, value = "結果", example = "true") val result: Boolean, @ApiModelProperty(required = true, value = "ステータス", example = "OK") val status: String ) @ApiOperation(value = "ヘルスチェック") @RequestMapping(value = "/health-check", method = arrayOf(RequestMethod.GET)) fun index(): Response<HealthCheck> { return Response(HealthCheck(true, "OK")) } @ApiOperation(value = "ヘルスチェック") @RequestMapping(value = "/health-check/elasticsearch", method = arrayOf(RequestMethod.GET)) fun elasticsearch(): Response<HealthCheck> { return Response(HealthCheck(true, elasticsearchClient.foo())) } }
- elasticsearch()ではfoo()メソッドを利用しています。
- 運用時ではelasticsearch()はElasticsearchへリクエストを送信し正常に稼働しているかのヘルスチェックに利用します。
- では、テストコードでfoo()メソッドをモック化します。
テストコード
@RunWith(SpringJUnit4ClassRunner::class) @ContextConfiguration(classes = arrayOf(Application::class)) @WebAppConfiguration class HealthCheckControllerTest { lateinit var mvc: MockMvc lateinit var elasticsearchClient: ElasticsearchClient lateinit var target: HealthCheckController @Before fun setup() { elasticsearchClient = Mockito.mock(ElasticsearchClient::class.java) target = HealthCheckController(elasticsearchClient) MockitoAnnotations.initMocks(this) mvc = MockMvcBuilders.standaloneSetup(target).build() } @Test fun testElasticsearch() { val type = Types.newParameterizedType(Response::class.java, HealthCheckController.HealthCheck::class.java) val adapter: JsonAdapter<Response<HealthCheckController.HealthCheck>> = Moshi.Builder().build().adapter(type) Mockito.`when`(elasticsearchClient.foo()).thenReturn("NG") val result: MvcResult = mvc.perform(get("/health-check/elasticsearch")) .andExpect(status().isOk()).andReturn() val response = adapter.fromJson(result.response.contentAsString) assertThat(response.value.result, Is.`is`(true)) assertThat(response.value.status, Is.`is`("NG")) } }
setup()メソッド
@Before fun setup() { elasticsearchClient = Mockito.mock(ElasticsearchClient::class.java) target = HealthCheckController(elasticsearchClient) MockitoAnnotations.initMocks(this) mvc = MockMvcBuilders.standaloneSetup(target).build() }
- 上記のコードでHealthCheckControllerのElasticsearchClientクラスインスタンスをモック化しています。
モック化はどこで?
Mockito.`when`(elasticsearchClient.foo()).thenReturn("NG")
- 上記のコードでfoo()メソッドの返り値が"NG"になるようにしています。
assertThat(response.value.result, Is.`is`(true)) assertThat(response.value.status, Is.`is`("NG"))
- アサーションでは正しく"NG"になるかチェックを行っています。