目次
Spring Bootでの実用的な機能をわかりやすく解説中
Spring Boot アプリケーションのテストを記述するためには spring-boot-starter-test
を利用します。依存ライブラリとして JUnit や Mockito などが利用されています。以下の公式ドキュメントを参考にしつつ簡単な使用方法をまとめます。
- チュートリアル
- ユーザーガイド
- JUnit 4.12 API (2017/9/10 に GA リリースされた JUnit 5 は
./gradlew dependencies
によるとまだ利用できないようです。)
サンプルプロジェクト
以下のような構成のサンプルプロジェクトを用意してテストコードを記述してみます。
.
|-- build.gradle
|-- gradle
| `-- wrapper
| |-- gradle-wrapper.jar
| `-- gradle-wrapper.properties
|-- gradlew
|-- gradlew.bat
`-- src
|-- main
| `-- java
| `-- hello
| |-- Application.java
| |-- HelloController.java
| `-- HelloService.java
`-- test
`-- java
`-- hello
|-- HelloControllerIT.java
|-- HelloControllerITWithMock.java
|-- HelloControllerTest.java
`-- HelloServiceTest.java
build.gradle
buildscript {
ext {
springBootVersion = '1.5.3.RELEASE'
}
repositories {
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
}
}
apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'idea'
apply plugin: 'org.springframework.boot'
jar {
baseName = 'gs-spring-boot'
version = '0.1.0'
}
repositories {
mavenCentral()
}
sourceCompatibility = 1.8
targetCompatibility = 1.8
dependencies {
compile('org.springframework.boot:spring-boot-starter-web')
testCompile('org.springframework.boot:spring-boot-starter-test')
}
src/main/java/hello/Application.java
package hello;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;
@SpringBootApplication
@EnableScheduling
public class Application {
public static void main(String[] args) throws Exception {
SpringApplication.run(Application.class);
}
}
src/main/java/hello/HelloController.java
package hello;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
@RestController
public class HelloController {
@Autowired
private HelloService helloService;
@RequestMapping("/")
public String index() {
return helloService.greet();
}
}
src/main/java/hello/HelloService.java
package hello;
import org.springframework.stereotype.Service;
@Service
public class HelloService {
public String greet() {
return "Hello World";
}
}
テストコード
以下のコマンドでテストを実行できます。
./gradlew test
一部のテストだけを実行したい場合は以下のようにします。
./gradlew test --tests "hello.HelloServiceTest"
サービス層の単体テスト
src/test/java/hello/HelloServiceTest.java
package hello;
import static org.assertj.core.api.Assertions.assertThat;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class)
@SpringBootTest
public class HelloServiceTest {
@Autowired
private HelloService helloService;
@Test
public void sampleTest() throws Exception {
assertThat(helloService.greet()).contains("Hello");
}
}
コントローラ層の単体テスト
src/test/java/hello/HelloControllerTest.java
後述の @AutoConfigureMockMvc
ではなく @WebMvcTest
を用いて、指定したコントローラ Bean だけをインスタンス化します。サービス層の Bean もインスタンス化されていないため、@MockBean
を用いてコントローラが依存するサービスのモックを準備します。返す値は Mockito
の when
で設定します。
package hello;
import static org.hamcrest.Matchers.containsString;
import static org.mockito.Mockito.when;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
@RunWith(SpringRunner.class)
@WebMvcTest(HelloController.class)
public class HelloControllerTest {
@Autowired
private MockMvc mockMvc;
@MockBean
private HelloService helloService;
@Test
public void sampleTest() throws Exception {
when(helloService.greet()).thenReturn("Hello Mock");
mockMvc.perform(get("/"))
.andExpect(status().isOk())
.andExpect(content().string(containsString("Hello Mock")));
}
}
結合テスト
src/test/java/hello/HelloControllerIT.java
RANDOM_PORT
で実際にサーバーを起動し、@Autowired
した TestRestTemplate
を用いて HTTP リクエストします。期待したレスポンスが得られるかどうかをテストします。
package hello;
import static org.assertj.core.api.Assertions.assertThat;
import java.net.URI;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.embedded.LocalServerPort;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
public class HelloControllerIT {
@LocalServerPort
private int port;
@Autowired
private TestRestTemplate template;
@Test
public void sampleTest() throws Exception {
URI uri = new URI("http://localhost:" + port + "/");
String responseBody = template.getForObject(uri, String.class);
assertThat(responseBody).isEqualTo("Hello World");
}
}
@AutoConfigureMockMvc
アノテーションを利用し、MockMvc
を @Autowired
して利用すると、サーバーを起動せず比較的短時間で完了する結合テストが実施できます。
src/test/java/hello/HelloControllerITWithMock.java
package hello;
import static org.hamcrest.Matchers.equalTo;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import org.junit.Test;
import org.junit.runner.RunWith;
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.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureMockMvc
public class HelloControllerITWithMock {
@Autowired
private MockMvc mockMvc;
@Test
public void sampleTest() throws Exception {
mockMvc.perform(get("/"))
.andExpect(status().isOk())
.andExpect(content().string(equalTo("Hello World")));
}
}
記事の執筆者にステッカーを贈る
有益な情報に対するお礼として、またはコメント欄における質問への返答に対するお礼として、 記事の読者は、執筆者に有料のステッカーを贈ることができます。
さらに詳しく →Feedbacks
ログインするとコメントを投稿できます。
関連記事
- Spring Security フォームログインのサンプルコードSpring フレームワークによる Web アプリケーション開発で、ログイン処理を実装する際は Spring Security が便利です。ここでは特に Spring Boot で Web アプリケーションを開発する場合を対象とし、フォームによる ID/Password ログインを行うためのサンプルコードをまとめます。 公式ドキュメント [Spring Security チュートリアル](http...
- Java配列の宣言方法 (C/C++との違い)Javaの配列 Javaの配列宣言方法はC/C++と似ているようで若干異なる。 初期化しない場合 C/C++の int array[10]; はJavaでは int array[] = new int[10]; となる。同様にC/C++の int array[3][3]; はJavaでは int array[][] = new int[3][3]; となる。 初期化
- PlantUML による UML 図の描き方PlantUML はテキスト形式で表現されたシーケンス図やクラス図といった UML (Unified Modeling Language) 図の情報から画像を生成するためのツールです。簡単な使い方をまとめます。 インストール方法の選択 Atom や Eclipse のプラグインをインストールしてエディタから利用する方法、JAR をダウンロードして Java コマンドで実行する方法、Redmine ...
- Akka HTTP サンプルコード (Scala)Akka アクターを用いて実装された汎用 HTTP フレームワークです。Spray の後継です。コアモジュールである akka-http-core は 2016/2/17 に experimental が外れました。akka-http などのいくつかのサブモジュールは 2016/3/1 現在 experimental のままですが、基本的な
- Kestrel の使用例Kestrel は Message Queue (MQ) の実装のひとつです。一般に MQ はアプリケーション間やプロセス間、スレッド間で非同期に通信するために用いられます。メッセージの送信側は MQ に書き込めば受信側の応答を待たずに次の処理に非同期に進むことができます。Kestrel はわずか 2500 行程の Scala で実装されており JVM で動作します。MQ 自体はメモリ上に存在する...