Spring アプリケーションのテスト入門:単体テスト・統合テスト

Java

はじめに

テストはアプリケーションの品質を確保するために不可欠です。単体テストや統合テストを通じて、コードの信頼性を高める方法を初心者向けに解説します。具体的なサンプルコードを交えながら、テストの基礎を学びましょう。

テストの種類

アプリケーション開発において、主に以下の3種類のテストを行います。

  1. 単体テスト(Unit Test)
    コードの最小単位(関数やメソッド)が正しく動作するかを確認します。
  2. 統合テスト(Integration Test)
    複数のコンポーネントが連携して正しく動作するかを検証します。

環境準備

テストには JUnitMockMVC を使用します。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

まとめ

テストの重要性

  1. 品質の向上
    テストを通じてバグを早期に発見できます。
  2. コードの信頼性
    コードが正しく動作していることを保証できます。
  3. 将来の変更への対応
    コードが変わっても、既存機能の動作確認が容易になります。

テストは面倒に感じるかもしれませんが、品質を保つために非常に重要です。この機会にJUnitやMockMVCを使ったテストを実践してみましょう!

コメント

タイトルとURLをコピーしました