Spring Bootの初期テスト導入を完全ガイド!JUnit 5とSpring Boot Testの基本を初心者向けに解説
生徒
「Spring Bootでテストを書きたいんですが、最初にどうすればいいのかよく分かりません…JUnitとかSpring Boot Testとか出てきて混乱してます。」
先生
「Spring Bootでのテストは、JUnit 5とSpring Boot Testの2つを使うのが一般的です。最初の設定や書き方をおさえれば、難しくないですよ。」
生徒
「JUnitって名前だけ聞いたことありますけど、どんなふうに書けばいいんですか?」
先生
「じゃあ、JUnit 5の基本と、Spring Boot Testの使い方を順番に見ていきましょう!」
1. JUnit 5とは?Spring Bootとの関係
JUnit(ジェイユニット)は、Javaプログラムが正しく動くかを確認するための「自動テスト用フレームワーク」です。現在、Spring Bootで標準的に利用されているのが、最新バージョンであるJUnit 5(別名:JUnit Jupiter)です。
プログラミング初心者の方にとって、テストを自分で手動で行うのは時間がかかり、ミスも起きやすいものです。JUnit 5を導入すれば、ボタン一つでプログラムの動作チェックを自動化できるため、開発効率が劇的に向上します。
Spring BootでJUnit 5を使い始めるのは非常に簡単です。プロジェクト作成時にspring-boot-starter-testというライブラリ(便利な道具箱のようなもの)を依存関係に追加するだけで準備が整います。この中には、テストを強力にサポートする以下のツールが最初からセットになっています。
- JUnit 5:テストを実行するためのメインエンジン
- AssertJ:テスト結果の検証(アサーション)を読みやすく書くためのライブラリ
- Mockito:特定の動作を模倣する「モック」を作成するツール
// build.gradle (Gradleの場合の依存関係定義)
dependencies {
// これだけでJUnit 5を含むテスト環境がすべて揃います
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
Spring Bootでは、この設定ひとつで「テストを書き、実行し、結果を確認する」という一連のサイクルがすぐに始められるようになっています。これにより、複雑な設定に悩むことなく、本来の目的である「正しいコードを書くこと」に集中できるのが大きなメリットです。
2. JUnit 5の基本的なテストの書き方
JUnit 5を使用してテストコードを書く際は、まず「どのような結果になれば正解か」という期待値を定義することから始めます。最も基本となるのは、テストしたいメソッドに@Testアノテーションを付与することです。これにより、メインメソッド(main)がなくても、その箇所だけを独立して実行できるようになります。
プログラミング初心者の方でもイメージしやすいよう、簡単な「お買い物計算」を例に、具体的なコードの書き方を見ていきましょう。
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
// テストクラスの名前は「テスト対象 + Test」とするのが一般的です
public class CalculatorTest {
@Test
void 100円の商品を2個買った時の合計金額をテストする() {
// 1. 準備:テストに必要なデータを用意する
int price = 100;
int quantity = 2;
// 2. 実行:実際に計算を行う(ここでは 100 * 2)
int total = price * quantity;
// 3. 検証:結果が期待通り(200)になっているか確認する
// assertEquals(期待する値, 実際の計算結果)
assertEquals(200, total);
}
}
このコードのポイントは、assertEqualsというメソッドです。これは「第一引数(期待値)」と「第二引数(実際の値)」が一致するかをJUnitが自動で判定してくれる仕組みです。もし計算ロジックが間違っていて結果が150になれば、テストは失敗(Red)となり、一目でバグに気づくことができます。
JUnit 5では、メソッド名を日本語で書くことも可能です。何を確認するためのテストなのかを具体的に記述することで、後から見返した際やチーム開発においても、仕様書のような役割を果たしてくれるため、初心者の方こそ丁寧な命名を心がけるのが上達の近道です。
3. Spring Boot Testとは何か?統合テストの第一歩
Spring Boot Test(スプリング・ブート・テスト)は、アプリケーションの「部品(クラス)」同士が組み合わさった時に、正しく連携して動くかを確認するための強力な仕組みです。これまでは「計算機」のような単体での動作を確認してきましたが、実際のアプリではデータベースや他の機能と複雑に絡み合います。
最大の特徴は@SpringBootTestという魔法のようなアノテーションです。これを使用すると、本番環境と同じようにSpringの「DIコンテナ」という管理箱を起動させることができます。これにより、自分でインスタンス(new)を作らなくても、Springが自動で必要な部品を準備してくれるため、より実戦に近い「統合テスト」が容易になります。
例えば、入力した名前に挨拶を添えて返す「挨拶サービス」をテストする場合を考えてみましょう。
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import static org.junit.jupiter.api.Assertions.assertEquals;
@SpringBootTest // アプリ全体の設定を読み込み、テスト環境を構築します
class GreetingServiceTest {
@Autowired // Springが管理しているGreetingServiceを自動でセット(注入)します
private GreetingService greetingService;
@Test
void ユーザー名に対して正しい挨拶が返ってくるか検証する() {
// 1. 準備:テストに使う名前を用意
String name = "田中";
// 2. 実行:Springによって注入されたサービスを実行
String message = greetingService.makeMessage(name);
// 3. 検証:期待通りのメッセージになっているか確認
assertEquals("こんにちは、田中さん!", message);
}
}
このテストのすごい所は、@Autowired(オートワイヤード)という機能です。本来ならテストコード内で複雑な設定を書く必要がありますが、この1行を書くだけで、Springが裏側で「テストに必要な部品」を探してきて自動的に組み立ててくれます。プログラミング未経験の方でも、この仕組みのおかげで「準備」の手間を大幅に減らし、ロジックの検証に集中できるのがSpring Boot Testの大きなメリットです。
4. コントローラのテストには@WebMvcTest
Webアプリケーション開発において、ユーザーからのリクエストを受け取る「窓口」であるコントローラの動作確認は欠かせません。しかし、テストのたびにアプリ全体を起動すると時間がかかってしまいます。そこで重宝するのが@WebMvcTestです。
このアノテーションの最大の特徴は、Web層(コントローラ周り)だけに絞ってテスト環境を構築できる点です。データベースなどの複雑な設定を読み込まないため、テストの起動が非常に高速で、修正後の動作確認をリズムよく行えます。まさに「軽量でピンポイントな検証」に最適なツールです。
初心者の方でも扱いやすいよう、「/hello」というURLにアクセスすると「Hello World」という文字を返すだけのシンプルなコントローラを例に、具体的なテスト方法を見ていきましょう。
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.test.web.servlet.MockMvc;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
@WebMvcTest(MyController.class) // 指定したコントローラだけをテスト対象にします
class MyControllerTest {
@Autowired
private MockMvc mockMvc; // ブラウザの代わりをしてくれる便利なツールです
@Test
void helloエンドポイントにアクセスして文字が返ってくるか確認する() throws Exception {
// 1. 実行 & 2. 検証
// 「/hello」にGETリクエストを送り、結果をチェックします
mockMvc.perform(get("/hello"))
.andExpect(status().isOk()) // ステータスコードが200(成功)であること
.andExpect(content().string("Hello World")); // 画面に「Hello World」と出ること
}
}
ここで登場するMockMvcは、実際のブラウザを使わずに「擬似的なリクエスト」を送ってくれる仕組みです。これを使えば、「特定のURLを叩いたときに、正しい画面やメッセージが表示されるか」をプログラムで自動判定できます。
プログラミング未経験の方は、まず「ブラウザを操作する手順をコードで書いている」とイメージしてみてください。手動で何度もリロードして確認する手間が省けるだけでなく、一度書いておけば将来コードを変更した際のデグレ(先祖返り)防止にも役立ちます。
5. Mockitoを使った依存のモックと単体テストの効率化
テストを書いていると、「他のクラスの処理が終わらないと、自分のテストが進められない」という場面に遭遇します。例えば、データベースからデータを取得する処理や、外部システムと通信する処理などです。これを解決するのが、Mockito(モキート)というライブラリです。
Mockitoを使うと、本物のクラスの代わりに「偽物の部品(モック)」を置くことができます。プログラミング未経験の方なら、「ドラマの撮影で使う小道具」をイメージしてみてください。本物の電話がつながっていなくても、小道具の電話があれば「電話をかけるシーン」の練習ができるのと同じです。これにより、特定のロジックだけを切り離して、高速かつ確実にテストできるようになります。
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import static org.mockito.Mockito.when;
import static org.junit.jupiter.api.Assertions.assertEquals;
// Mockitoを使用するための設定です
@ExtendWith(MockitoExtension.class)
class MyServiceTest {
@Mock // 1. 偽物の部品(モック)を作成します。データベースなどの代わりになります
private MyRepository myRepository;
@InjectMocks // 2. 作成したモックを、テストしたいクラスに自動で組み込みます
private MyService myService;
@Test
void 特定のデータが返ってきた場合の処理をシミュレーションする() {
// 3. 「もしモックが呼ばれたら、この値を返す」という動きを予約します
// when(メソッド実行).thenReturn(返したい値)
when(myRepository.findData()).thenReturn("テスト用データ");
// 4. 実行:内部でモックが使われますが、テスト側で制御された値が返ります
String result = myService.process();
// 5. 検証:意図した通りに加工されているかチェック
assertEquals("テスト用データ 加工済み", result);
}
}
このコードの大きなメリットは、MyRepositoryの中身が完成していなくても、あるいはデータベースが止まっていても、MyServiceのロジックが正しいかどうかを今すぐ確認できる点にあります。
「本物の動き」に依存せず、「もしAというデータが来たらBと返す」という条件を自由に作れるため、エラーが起きた時の複雑なパターンの検証も容易になります。JUnit 5とMockitoを組み合わせることで、開発のスピードとコードの品質を同時に高めることが可能になります。
6. Spring Bootのテストでよくあるエラーと対処法
依存関係が注入されない → @Autowiredが付いていない、またはテストクラスに@SpringBootTestが付いていない場合に発生します。
MockMvcがnullになる → @WebMvcTestとMockMvcの組み合わせを確認しましょう。
アプリ全体が起動して重い → 単体テストでは@SpringBootTestではなく@MockBeanなどを活用して部分的にテストを行いましょう。
まとめ
Spring Bootにおけるテスト導入は、JUnit 5とSpring Boot Testを中心に理解することで一気に実践しやすくなります。とくに初心者は「テストの種類」「アノテーションの使い分け」「DIを利用したテストの考え方」で混乱しやすいため、今回の記事のように段階的に学ぶ方法が非常に効果的です。JUnit 5の基本構文を押さえておけば、単体テストで小さな処理を検証する自信がつき、さらにSpring Boot Testを使うことでアプリ全体を動かしながらの統合テストへスムーズに進めます。こうした学習の積み重ねは、品質の高いアプリケーションを構築するうえで欠かせない基礎となります。
Spring Boot Testの魅力は、DIコンテナをそのまま利用できるため、実際のアプリケーションに近い環境で動作確認ができる点にあります。同時に、@WebMvcTestで軽量なコントローラテストを行ったり、Mockitoで依存のモックを作成したりと、目的に応じてテスト手法を切り替える柔軟性があることも大きな利点です。たとえば、コントローラの挙動確認だけを行うならアプリ全体の起動は不要であり、MockMvcのような仕組みを使えば効率的な検証ができます。
また、実際のテスト現場では「依存が注入されない」「MockMvcがnullになる」といった初歩的なエラーが起こりやすいため、アノテーションの付け方やテスト種類の選択を正しく行うことが重要です。記事で紹介したように、単体テスト・統合テスト・コントローラテストなどの違いを明確に理解しておくことで、どの場面でどのアノテーションを使うべきか判断できるようになります。
さらに、テストを書くことは単にエラーを見つけるためだけではなく、アプリケーションの仕様を自分自身で整理し、動作の根拠を明確にする役割も持っています。コードの変更による影響範囲も確認しやすくなり、結果として開発効率と品質の向上につながります。JUnit 5とSpring Boot Testの使い分けを身につけることで、テストが難しいものではなく、むしろ開発を支える強力な味方だと感じられるはずです。
以下に、今回理解した内容を実践に近い形でまとめたサンプルコードを掲載します。Spring Boot TestとMockitoを組み合わせたよくあるテスト例です。
サンプルプログラム:Spring Boot Test + Mockitoの組み合わせ
@SpringBootTest
class SummaryServiceTest {
@MockBean
private UserRepository userRepository;
@Autowired
private SummaryService summaryService;
@Test
void testSummaryOutput() {
when(userRepository.findName()).thenReturn("山田");
String result = summaryService.createMessage();
assertEquals("こんにちは山田さん", result);
}
}
この例では、Spring Boot Testによってアプリケーション全体を起動しつつ、Mockitoの@MockBeanで依存をモック化しています。実際の開発でも頻繁に利用される構成で、サービス層の動きだけを正確に検証できます。JUnit 5の@Testを使った単体テストの基礎に加え、Spring Boot Testの強みであるDIと統合的なテスト環境の両方を体験できる形になっており、初心者にとって非常に有効な学習ステップとなるでしょう。
テスト設計の幅が広がることで、開発全体の見通しも改善されます。重要なのは、目的に応じて必要なテストを選び、過不足ない形で実装できる判断力を身につけることです。JUnit 5の書き方、Spring Boot Testのアノテーション、コントローラ向けの@WebMvcTest、外部依存を切り離すMockitoなど、今回学んだポイントを組み合わせることで、あらゆるテストパターンに対応できる柔軟なテスト設計が可能になります。
それでは、学んだ内容をもう一度整理するために、先生と生徒の振り返り会話を見ていきましょう。
生徒
「JUnit 5でテストを書く流れが分かって、自分でも書けそうな気がしてきました!@Testだけで簡単に動かせるのが良いですね。」
先生
「その調子です。Spring Boot Testを組み合わせると、実際のアプリケーションに近い動作を確認できるので、さらに理解が深まりますよ。」
生徒
「@WebMvcTestでコントローラだけをテストできるのも便利ですね。MockMvcでリクエストを試せるのは実際の動作に近い感じがして楽しいです。」
先生
「そうですね。テストする対象を絞ると効率も上がりますし、エラー原因も分かりやすくなります。」
生徒
「Mockitoで依存をモック化できるのも役立ちますね。外部の影響を受けずにロジックだけ確認できるのは大きいです。」
先生
「その理解はとても大事ですよ。テストを正しく書けるようになると、アプリケーションの品質を自分で守れるエンジニアになれます。」