ส่วนทดสอบ Spring Boot: @WebMvcTest และ @DataJpaTest
ใช้ @WebMvcTest เพื่อทดสอบคอนโทรลเลอร์แบบแยกอิสระ และใช้ @DataJpaTest เพื่อทดสอบชั้นรีโพซิทอรี
ส่วนทดสอบ Spring Boot: @WebMvcTest และ @DataJpaTest เป็นบทเรียน Java Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Java Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Java Academy มีบทเรียนทั้งหมด 4 บทเรียน
ส่วนย่อยสำหรับการทดสอบคืออะไร
ส่วนย่อยสำหรับการทดสอบจะโหลดเฉพาะส่วนที่เกี่ยวข้องของบริบท Spring สำหรับชั้นงานหนึ่งโดยเฉพาะ ทำงานได้เร็วกว่า @SpringBootTest ซึ่งโหลดทุกอย่าง และช่วยแยกชั้นงานที่กำลังทดสอบออกจากส่วนอื่น
@WebMvcTest: เฉพาะชั้นตัวควบคุม
@WebMvcTest(UserController.class) จะโหลดเฉพาะชั้นเว็บ ได้แก่ ตัวควบคุม ตัวกรอง การกำหนดค่าความปลอดภัย และ Jackson ส่วนบริการและคลังเก็บข้อมูลต้องจำลองด้วย @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 อื่น เช่น บริการและเว็บ
@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());
}
}การแทนที่ H2 ด้วยฐานข้อมูลจริงใน @DataJpaTest
ใช้ @AutoConfigureTestDatabase(replace = Replace.NONE) เพื่อเรียกใช้ @DataJpaTest กับฐานข้อมูลจริงที่กำหนดค่าไว้ใน application.properties แทน H2
@DataJpaTest
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
class ProductRepositoryTest {
// Uses the configured PostgreSQL, not H2
}@JsonTest: เฉพาะการแปลงเป็น JSON
@JsonTest จะโหลดการกำหนดค่า Jackson ใช้ JacksonTester เพื่อตรวจสอบว่าออบเจ็กต์ถูกแปลงเป็น JSON และอ่านกลับจาก JSON ได้ตามที่คาดไว้
@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 ใช้ทดสอบไคลเอนต์ HTTP ที่ทำงานบน RestTemplate หรือ WebClient โดยจะกำหนดค่า MockRestServiceServer เพื่อจำลองการตอบกลับ HTTP
@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 และย้อนกลับธุรกรรมโดยอัตโนมัติ ใช้ Replace.NONE สำหรับฐานข้อมูลจริง ใช้ @JsonTest สำหรับการแปลงข้อมูล และ @RestClientTest สำหรับไคลเอนต์ HTTP
คำถามที่พบบ่อย
บทเรียน “ส่วนทดสอบ Spring Boot: @WebMvcTest และ @DataJpaTest” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “ส่วนทดสอบ Spring Boot: @WebMvcTest และ @DataJpaTest” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Java Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Java Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “ส่วนทดสอบ Spring Boot: @WebMvcTest และ @DataJpaTest”
ใช้ @WebMvcTest เพื่อทดสอบคอนโทรลเลอร์แบบแยกอิสระ และใช้ @DataJpaTest เพื่อทดสอบชั้นรีโพซิทอรี คุณปฏิบัติ Java Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Java Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน Java Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน
บทเรียน “ส่วนทดสอบ Spring Boot: @WebMvcTest และ @DataJpaTest” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน Java Academy นี้ได้ไหม
ได้ บทเรียน Java Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- การทดสอบแบบกำหนดพารามิเตอร์ด้วย @CsvSource และ @MethodSource
- Mockito ขั้นสูง: ตัวจับอาร์กิวเมนต์และสายลับ
- ส่วนทดสอบ Spring Boot: @WebMvcTest และ @DataJpaTest
- Testcontainers: การทดสอบการผสานรวมกับฐานข้อมูลจริง