spring-boot-test-patterns について
JUnit 5、Mockito、Testcontainersを使うSpring Boot開発者向けのテストパターンガイドです。単体・スライス・統合テストを整理し、テスト範囲の選択とSpringコンテキストの負荷管理に役立ちます。
主な機能
- 01Mockitoによる単体テスト
- 02レイヤー別のSpringテストスライス
- 03MockMvcによるREST APIテスト
- 04Testcontainersのサービス接続
- 05依存関係とCI/CDのガイド
活用シーン
- 01サービスやリポジトリの分離テスト
- 02実データベースを使う統合テスト
- 03RESTコントローラーとAPIの検証
- 04自動テストパイプラインの構築
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ giuseppe-trisciuoglio/ developer-kit --skill spring-boot-test-patternsインストール後、Claude Code で/spring-boot-test-patternsを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/api-reference.mdbest-practices.mdci-cd-configuration.mdslice-testing.mdtest-dependencies.mdtestcontainers-setup.mdunit-testing.mdworkflow-patterns.md詳細
Spring Boot のテストパターン
概要
JUnit 5、Mockito、Testcontainers、およびパフォーマンスを最適化したスライステストパターンを使用して、Spring Boot アプリケーション向けの堅牢なテストスイートを作成するための包括的なガイダンスです。
使用する場面
- モック化した依存関係を使用して、サービスやリポジトリのユニットテストを作成する場合
- Testcontainers を使って実際のデータベースを用いた統合テストを実装する場合
@WebMvcTestまたは MockMvc を使って REST API をテストする場合- Spring Boot 3.5+ でコンテナー管理に
@ServiceConnectionを設定する場合
クイックリファレンス
| テストの種類 | アノテーション | 目標時間 | 用途 |
|---|---|---|---|
| ユニットテスト | @ExtendWith(MockitoExtension.class) | < 50ms | Spring コンテキストを使わないビジネスロジック |
| リポジトリテスト | @DataJpaTest | < 100ms | 最小限のコンテキストでのデータベース操作 |
| コントローラーテスト | @WebMvcTest / @WebFluxTest | < 100ms | REST API レイヤーのテスト |
| 統合テスト | @SpringBootTest | < 500ms | コンテナーを使用した完全なアプリケーションコンテキスト |
| Testcontainers | @ServiceConnection / @Testcontainers | さまざま | 実際のデータベース/メッセージブローカーのコンテナー |
主な概念
テストアーキテクチャの考え方
- ユニットテスト — Spring コンテキストを使わない、高速で分離されたテスト(< 50ms)
- スライステスト — 特定のレイヤーに限定した最小限の Spring コンテキスト(< 100ms)
- 統合テスト — 実際の依存関係を使用する完全な Spring コンテキスト(< 500ms)
主なアノテーション
Spring Boot テスト:
@SpringBootTest— 完全なアプリケーションコンテキスト(使用は最小限にしてください)@DataJpaTest— JPA コンポーネントのみ(リポジトリ、エンティティ)@WebMvcTest— MVC レイヤーのみ(コントローラー、@ControllerAdvice)@WebFluxTest— WebFlux レイヤーのみ(リアクティブコントローラー)@JsonTest— JSON シリアライズコンポーネントのみ
Testcontainers:
@ServiceConnection— Testcontainer を Spring Boot に接続します(3.5+)@DynamicPropertySource— 実行時に動的プロパティを登録します@Testcontainers— Testcontainers のライフサイクル管理を有効にします
手順
1. ユニットテストのパターン
モック化した依存関係を使ってビジネスロジックをテストします。
@ExtendWith(MockitoExtension.class)
class UserServiceTest {
@Mock
private UserRepository userRepository;
@InjectMocks
private UserService userService;
@Test
void shouldFindUserByIdWhenExists() {
when(userRepository.findById(1L)).thenReturn(Optional.of(user));
Optional<User> result = userService.findById(1L);
assertThat(result).isPresent();
verify(userRepository).findById(1L);
}
}
高度なパターンについては、unit-testing.md を参照してください。
2. スライステストのパターン
特定のレイヤーに絞ったテストスライスを使用します。
@DataJpaTest
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
@TestContainerConfig
class UserRepositoryIntegrationTest {
@Autowired
private UserRepository userRepository;
@Test
void shouldSaveAndRetrieveUser() {
User saved = userRepository.save(user);
assertThat(userRepository.findByEmail("[email protected]")).isPresent();
}
}
すべてのスライスパターンについては、slice-testing.md を参照してください。
3. REST API テストのパターン
MockMvc でコントローラーをテストします。
@WebMvcTest(UserController.class)
class UserControllerTest {
@Autowired
private MockMvc mockMvc;
@MockBean
private UserService userService;
@Test
void shouldGetUserById() throws Exception {
mockMvc.perform(get("/api/users/1"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.email").value("[email protected]"));
}
}
4. @ServiceConnection を使った Testcontainers
Spring Boot 3.5+ でコンテナーを設定します。
@TestConfiguration
public class TestContainerConfig {
@Bean
@ServiceConnection
public PostgreSQLContainer<?> postgresContainer() {
return new PostgreSQLContainer<>("postgres:16-alpine");
}
}
テストクラスに @Import(TestContainerConfig.class) を付けて適用します。
詳細な設定については、testcontainers-setup.md を参照してください。
5. 依存関係の追加
必要なテスト依存関係を含めます。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>junit-jupiter</artifactId>
<version>1.19.0</version>
<scope>test</scope>
</dependency>
依存関係の一覧については、test-dependencies.md を参照してください。
6. CI/CD の設定
自動テスト用に GitHub Actions を設定します。
name: Tests
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
services:
docker:
image: docker:20-dind
steps:
- uses: actions/checkout@v4
- name: Set up JDK 17
uses: actions/setup-java@v4
with:
distribution: 'temurin'
- name: Run tests
run: ./mvnw test
CI/CD のパターン全体については、ci-cd-configuration.md を参照してください。
検証チェックポイント
テストを実装した後、以下を確認してください。
- コンテナーの起動:
docker ps(testcontainer イメージを確認します) - コンテキストの読み込み:「Started Application in X.XX seconds」が起動ログに出力されていることを確認します
- テストの分離:テストを個別に実行し、相互に干渉しないことを確認します
例
@ServiceConnection を使った完全な統合テスト
@SpringBootTest
@Import(TestContainerConfig.class)
class OrderServiceIntegrationTest {
@Autowired
private OrderService orderService;
@Autowired
private UserRepository userRepository;
@Test
void shouldCreateOrderForExistingUser() {
User user = userRepository.save(User.builder()
.email("[email protected]")
.build());
Order order = orderService.createOrder(user.getId(), List.of(
new OrderItem("SKU-001", 2)
));
assertThat(order.getId()).isNotNull();
assertThat(order.getStatus()).isEqualTo(OrderStatus.PENDING);
}
}
実際のデータベースを使った @DataJpaTest
@DataJpaTest
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
@TestContainerConfig
class UserRepositoryTest {
@Autowired
private UserRepository userRepository;
@Test
void shouldFindByEmail() {
userRepository.save(User.builder()
.email("[email protected]")
.build());
assertThat(userRepository.findByEmail("[email protected]"))
.isPresent();
}
}
エンドツーエンドの例については、workflow-patterns.md を参照してください。
ベストプラクティス
- 適切なテストの種類を使用する:リポジトリには
@DataJpaTest、コントローラーには@WebMvcTest、完全な統合テストの場合にのみ@SpringBootTestを使用します @ServiceConnectionを優先する:Spring Boot 3.5+では、コンテナー管理を簡潔にするため、@DynamicPropertySourceよりも@ServiceConnectionを優先します- テストの決定性を保つ:
@BeforeEachですべてのテストデータを明示的に初期化します - レイヤーごとに整理する:コンテキストキャッシュを最大限に活用できるよう、テストをレイヤーごとにグループ化します
- TestcontainersをJVMレベルで再利用する(
withReuse(true)+TESTCONTAINERS_REUSE_ENABLE=true) @DirtiesContextを避ける:コンテキストの再構築を強制するため、パフォーマンスが大幅に低下します- 外部サービスはモックし、必要な場合にのみ実際のデータベースを使用します
- パフォーマンスの目標:ユニットテスト < 50ms、スライステスト < 100ms、統合テスト < 500ms
制約と警告
- 絶対に必要な場合を除き、
@DirtiesContextは使用しないでください(コンテキストの再構築を強制します) - 異なる設定の
@MockBeanを混在させないでください(別々のコンテキストが作成されます) - TestcontainersにはDockerが必要です。CI/CDパイプラインでDockerがサポートされていることを確認してください
- テストの実行順序に依存しないでください。各テストは独立している必要があります
@TestPropertySourceの使用には注意してください(別々のコンテキストが作成されます)- ユニットテストに
@SpringBootTestを使用しないでください。代わりに通常のMockitoを使用してください - 異なる
@MockBean設定によってコンテキストキャッシュが無効になる場合があります - テストでは変更可能な静的状態を避けてください(不安定なテストの原因になります)
参考資料
- test-dependencies.md — Maven/Gradleのテスト依存関係
- unit-testing.md — Mockitoパターンを使ったユニットテスト
- slice-testing.md — リポジトリ、コントローラー、JSONのスライステスト
- testcontainers-setup.md — Testcontainersの設定パターン
- ci-cd-configuration.md — GitHub Actions、GitLab CI、Docker Compose
- api-reference.md — テストアノテーションとユーティリティの完全なリファレンス
- best-practices.md — テストパターンと最適化
- workflow-patterns.md — 統合テストの完全な例