はじめに
SpringBootで作ったWebアプリにテストコードを実装しました。
実行環境
OS:Mac
JUnit:JUnit5.8.2
Java:Amazon Corretto 8
Spring Boot:2.6.1
Gradle:gradle6.8
IDE:intellij idea community edition 2021.1
テスト環境を構築
spring-boot-starter-testを使用する
「spring-boot-starter-test」を使用することで、
SpringBoot上のコードをテストするのに必要なライブラリを使用出来ます。
含まれるライブラリは以下の通り
ライブラリ | 備考 |
---|---|
JUnit5 | Javaアプリケーションの単体テストのための事実上の標準ライブラリ。 |
Spring Test Spring Boot Test |
Spring Bootアプリケーションのユーティリティ。 統合テストのための機能をサポートしています。 |
AssertJ | 高機能なアサーションライブラリ。 |
Hamcrest | マッチャーオブジェクトのライブラリ。 オブジェクトの状態をテストするのに利用される。 |
Mockito | Javaモックフレームワーク。 テストするクラスが依存しているDI管理下のオブジェクトをモック化したりできる。 |
JSONassert | JSON のアサーションライブラリ。 |
JsonPath | JSONでもXPATHのように、クエリ形式で要素を検索したりするライブラリ。 |
build.gradleに依存関係を追加
「spring-boot-starter-test」を依存関係に追加します。
dependencies {
// ・・・
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
test {
useJUnitPlatform()
}
テストを書く
テストするWebアプリ
テストするWebアプリは「HelloWorld」を返すものです。
Controllerからリクエストを受け取り、Serviceから「HelloWorld」という文字列を取得してクライアントに返します。
@Controller
public class HelloWorldController {
private HelloWorldService helloworldService;
@Autowired
public HelloWorldController(HelloWorldService helloworldService) {
this.helloworldService = helloworldService;
}
@ResponseBody
@GetMapping
public String index() {
return helloworldService.getString();
}
}
@Service
public class HelloWorldService {
public String getString() {
return "HelloWorld";
}
}
spring-boot-starter-testでのテストの書き方
SpringBootベースのテストをする場合、テストクラスに@SpringBootTestを付与します。
@SpringBootTestを付与することでJUnitに拡張機能としてSpringExtensionが指定され、
以下の機能を使用できるようになります。
・Spring TestContextフレームワーク
JUnitなどのテストフレームワークにとらわれることなく、テストコードでDI管理やトランザクション機能をサポートします。
・MockMvc(Spring MVC テストフレームワーク)
Spring MVCアプリケーションのテストをサポートします。
Controllerをテスト
Controllerにリクエストし、「HelloWorld」を取得できることをテストします。
テストクラスには@SpringBootTestに加え、@AutoConfigureMockMvcも付与します。
@AutoConfigureMockMvcを付与するとMockMvcが自動構成されます。
これにより、Controllerや、依存するServiceを通常のサーバー実行時のように扱うことが出来ます。
ControllerへのリクエストはMockMvc、MockMvcRequestBuildersを使用し、
その結果はMockMvcResultMatchersでチェックします。
以下では「http://localhost/」にリクエストし、
結果、
httpステータスがOK(200)であること
コンテンツに「HelloWorld」が返していること
を検証しています。
今回はパラメータなしのリクエストを実行していますが、MockMvcRequestBuildersにURLパラメータを設定することも出来ます。
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
@SpringBootTest
@AutoConfigureMockMvc
public class HelloWorldControllerTest {
@Test
void HelloWorldが取得されることを確認(@Autowired MockMvc mvc) throws Exception {
mvc.perform(
MockMvcRequestBuilders.get("/"))
.andExpect(MockMvcResultMatchers.status().isOk())
.andExpect(MockMvcResultMatchers.content().string("HelloWorld"));
}
}
Serviceをテスト
Controllerのテストクラス同様に@SpringBootTestを付与します。
こちらではServiceをコンストラクタインジェクションを利用し、DI管理下のインスタンス取得しています。
Serviceのメソッドを通常通り実行し、返却値をアサーションライブラリで検証しています。
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import static org.assertj.core.api.Assertions.assertThat;
@SpringBootTest
public class HelloWorldServiceTest {
private final HelloWorldService helloWorldService;
@Autowired
public HelloWorldServiceTest(HelloWorldService helloworldService) {
this.helloWorldService = helloworldService;
}
@Test
void HelloWorldが取得されることを確認() throws Exception {
String result = helloWorldService.getString();
assertThat(result).isEqualTo("HelloWorld");
}
}
参考文献