Spring Bootテストスライス:@WebMvcTestと@DataJpaTest
@WebMvcTestでコントローラーを分離してテストし、@DataJpaTestでリポジトリ層をテストします。
「Spring Bootテストスライス:@WebMvcTestと@DataJpaTest」はCoddyKit上の無料Java Academyレッスンです。 これはレッスン3/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはJava Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Java Academyコースには全4レッスンが含まれています。
テストスライスとは
テストスライスは、特定のレイヤーに関係する Spring コンテキストの一部だけを読み込みます。すべてを読み込む @SpringBootTest より高速で、テスト対象のレイヤーを分離できます。
@WebMvcTest: コントローラーレイヤーのみ
@WebMvcTest(UserController.class) は、コントローラー、フィルター、セキュリティ設定、Jackson だけを含む Web レイヤーを読み込みます。サービスとリポジトリは @MockBean でモック化する必要があります。
@WebMvcTest(UserController.class)
class UserControllerTest {
@Autowired MockMvc mockMvc;
@MockBean UserService userService;
@Test
void get_user_returns_200() throws Exception {
given(userService.findById(1L)).willReturn(new UserDto(1L, "Alice"));
mockMvc.perform(get("/api/users/1"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.name").value("Alice"));
}
}MockMvc によるリクエストの構築
MockMvcRequestBuilders を使用してリクエストを構築します。POST/PUT のテストでは、ヘッダー、コンテンツタイプ、リクエストボディを設定します。
mockMvc.perform(post("/api/users")
.contentType(MediaType.APPLICATION_JSON)
.content("""{"name":"Bob","email":"bob@example.com"}"""))
.andExpect(status().isCreated())
.andExpect(header().exists("Location"));@WebMvcTest でのバリデーションのテスト
無効なリクエストボディを受け取ると、MethodArgumentNotValidException が発生します。400 ステータスとエラーレスポンスのボディを検証します。
mockMvc.perform(post("/api/users")
.contentType(MediaType.APPLICATION_JSON)
.content("""{"name":"","email":"bad"}"""))
.andExpect(status().isBadRequest())
.andExpect(jsonPath("$.errors.name").exists());@DataJpaTest: リポジトリレイヤーのみ
@DataJpaTest は、JPA リポジトリ、組み込みの H2 データベース、Hibernate、TestEntityManager を読み込みます。その他の Bean(サービス、Web レイヤー)は読み込まれません。
@DataJpaTest
class UserRepositoryTest {
@Autowired UserRepository repo;
@Autowired TestEntityManager em;
@Test
void find_by_email() {
em.persist(new User("Alice", "alice@example.com"));
em.flush();
Optional<User> found = repo.findByEmail("alice@example.com");
assertTrue(found.isPresent());
}
}TestEntityManager
TestEntityManager は EntityManager をラップし、persist()、flush()、find()、persistAndFlush() などの便利なメソッドを提供します。
User saved = em.persistAndFlush(new User("Bob", "bob@example.com"));
assertNotNull(saved.getId());
em.clear(); // detach all to force a real DB read
User fromDb = repo.findById(saved.getId()).orElseThrow();
assertEquals("Bob", fromDb.getName());@DataJpaTest のロールバック
各テストはトランザクション内で実行され、デフォルトではテスト後にロールバックされます。テスト間でデータが保持されないため、手動でクリーンアップしなくてもテストを分離できます。
@DataJpaTest // each @Test is rolled back automatically
class OrderRepositoryTest {
@Test @Transactional
void count_orders_is_zero_by_default() {
assertEquals(0, orderRepo.count());
}
}@DataJpaTest で H2 を実際の DB に置き換える
@AutoConfigureTestDatabase(replace = Replace.NONE) を使用すると、H2 の代わりに application.properties で設定した実際のデータベースに対して @DataJpaTest を実行できます。
@DataJpaTest
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
class ProductRepositoryTest {
// Uses the configured PostgreSQL, not H2
}@JsonTest: JSON シリアライズのみ
@JsonTest は Jackson の設定を読み込みます。JacksonTester を使用して、オブジェクトが期待どおりにシリアライズおよびデシリアライズされることを検証します。
@JsonTest
class UserDtoJsonTest {
@Autowired JacksonTester<UserDto> json;
@Test
void serializes_correctly() throws Exception {
UserDto dto = new UserDto(1L, "Alice", "alice@example.com");
assertThat(json.write(dto)).hasJsonPathStringValue("$.email");
}
}@RestClientTest: REST クライアントレイヤー
@RestClientTest は、RestTemplate または WebClient ベースの HTTP クライアントをテストします。HTTP レスポンスをモックする MockRestServiceServer を設定します。
@RestClientTest(WeatherClient.class)
class WeatherClientTest {
@Autowired WeatherClient client;
@Autowired MockRestServiceServer server;
@Test
void fetches_weather() {
server.expect(requestTo("/api/weather")).andRespond(withSuccess("""{"temp":22}""", APPLICATION_JSON));
Weather w = client.getWeather("Istanbul");
assertEquals(22, w.getTemp());
}
}@Import によるスライスの組み合わせ
スライスでは、設計上、多くの Bean が除外されます。スライスに必要な特定の設定クラスを追加するには、@Import(SomeConfig.class) を使用します。
@WebMvcTest(UserController.class)
@Import(SecurityConfig.class) // load security for auth tests
class SecuredControllerTest { ... }クイックチェック
@DataJpaTest はデフォルトでどのデータベースを使用しますか?
まとめ
@WebMvcTest は MockMvc を使用してコントローラーレイヤーをテストし、サービスは @MockBean でモック化します。@DataJpaTest は TestEntityManager と自動ロールバックを使用してリポジトリをテストします。実際の DB を使用するには Replace.NONE を指定します。シリアライズには @JsonTest、HTTP クライアントには @RestClientTest を使用します。
よくある質問
「Spring Bootテストスライス:@WebMvcTestと@DataJpaTest」レッスンは無料ですか?
はい。「Spring Bootテストスライス:@WebMvcTestと@DataJpaTest」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Java Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Java Academyコースには全4レッスンが含まれています。
「Spring Bootテストスライス:@WebMvcTestと@DataJpaTest」で何を学びますか?
@WebMvcTestでコントローラーを分離してテストし、@DataJpaTestでリポジトリ層をテストします。 ブラウザで直接実行するハンズオンコードでJava Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
Java Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのJava Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン3/4です。
「Spring Bootテストスライス:@WebMvcTestと@DataJpaTest」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このJava Academyレッスンでコードを書いて実行できますか?
はい。すべてのJava Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- @CsvSourceと@MethodSourceによるパラメータ化テスト
- Mockito応用:ArgumentCaptorとスパイ
- Spring Bootテストスライス:@WebMvcTestと@DataJpaTest
- Testcontainers:実データベースによる統合テスト