はじめに
テストはアプリケーションの品質を確保するために不可欠です。単体テストや統合テストを通じて、コードの信頼性を高める方法を初心者向けに解説します。具体的なサンプルコードを交えながら、テストの基礎を学びましょう。
テストの種類
アプリケーション開発において、主に以下の3種類のテストを行います。
- 単体テスト(Unit Test)
コードの最小単位(関数やメソッド)が正しく動作するかを確認します。 - 統合テスト(Integration Test)
複数のコンポーネントが連携して正しく動作するかを検証します。
環境準備
テストには JUnit と MockMVC を使用します。Spring Bootプロジェクトに以下の依存関係を追加してください。
build.gradle
Bash
dependencies {
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'org.mockito:mockito-core'
}
依存関係を追加したら、以下のコマンドでGradleを更新します。
Bash
./gradlew build
プロジェクト構成
以下はプロジェクト構成例です。
Plaintext
src/
├── main/
│ ├── java/
│ │ └── com/example/demo/
│ │ ├── controller/
│ │ │ └── CalculatorController.java
│ │ ├── service/
│ │ │ └── CalculatorService.java
│ │ └── SqlApplication.java
│ └── resources/
│ └── application.properties
└── test/
└── java/
└── com/example/demo/
├── controller/
│ └── CalculatorControllerTest.java
├── service/
│ └── CalculatorServiceTest.java
└── DemoApplicationTests.java
単体テストの実装
単体テストでは、ビジネスロジックを含むクラスをテストします。ここでは、簡単な計算を行うサービスクラスを例に解説します。
サンプルコード:CalculatorService
src/main/java/com/example/demo/service/CalculatorService.java
Java
package com.example.demo.service;
import org.springframework.stereotype.Service;
@Service
public class CalculatorService {
public int add(int a, int b) {
return a + b;
}
public int subtract(int a, int b) {
return a - b;
}
}
テストコード:CalculatorServiceTest
src/test/java/com/example/demo/service/CalculatorServiceTest.java
Java
package com.example.demo.service;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
class CalculatorServiceTest {
private final CalculatorService calculatorService = new CalculatorService();
@Test
void testAdd() {
int result = calculatorService.add(3, 5);
assertEquals(8, result, "3 + 5 should equal 8");
}
@Test
void testSubtract() {
int result = calculatorService.subtract(10, 4);
assertEquals(6, result, "10 - 4 should equal 6");
}
}
実行方法
以下のコマンドを実行してテストを実行します。
Bash
./gradlew test
統合テストの実装
統合テストでは、サービスとコントローラーの連携を検証します。ここでは、簡単なコントローラーを作成し、それをテストします。
サンプルコード:CalculatorController
src/main/java/com/example/demo/controller/CalculatorController.java
Java
package com.example.demo.controller;
import com.example.demo.service.CalculatorService;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class CalculatorController {
private final CalculatorService calculatorService;
public CalculatorController(CalculatorService calculatorService) {
this.calculatorService = calculatorService;
}
@GetMapping("/add")
public int add(@RequestParam int a, @RequestParam int b) {
return calculatorService.add(a, b);
}
@GetMapping("/subtract")
public int subtract(@RequestParam int a, @RequestParam int b) {
return calculatorService.subtract(a, b);
}
}
テストコード:CalculatorControllerTest
src/test/java/com/example/demo/controller/CalculatorControllerTest.java
Java
package com.example.demo.controller;
import com.example.demo.service.CalculatorService;
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.boot.test.mock.mockito.MockBean;
import org.springframework.test.web.servlet.MockMvc;
import static org.mockito.Mockito.*;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
@WebMvcTest(CalculatorController.class)
class CalculatorControllerTest {
@Autowired
private MockMvc mockMvc;
@MockBean
private CalculatorService calculatorService;
@Test
void testAdd() throws Exception {
// 振る舞いを定義
when(calculatorService.add(2, 3)).thenReturn(5);
mockMvc.perform(get("/add")
.param("a", "2")
.param("b", "3"))
.andExpect(status().isOk())
.andExpect(content().string("5"));
}
@Test
void testSubtract() throws Exception {
// 振る舞いを定義
when(calculatorService.subtract(3, 2)).thenReturn(1);
mockMvc.perform(get("/subtract")
.param("a", "3")
.param("b", "2"))
.andExpect(status().isOk())
.andExpect(content().string("1"));
}
}
実行方法
同じく以下のコマンドを実行してテストを確認します。
Bash
./gradlew test
まとめ
テストの重要性
- 品質の向上
テストを通じてバグを早期に発見できます。 - コードの信頼性
コードが正しく動作していることを保証できます。 - 将来の変更への対応
コードが変わっても、既存機能の動作確認が容易になります。
テストは面倒に感じるかもしれませんが、品質を保つために非常に重要です。この機会にJUnitやMockMVCを使ったテストを実践してみましょう!
コメント