0Pricing
Java Academy · บทเรียน

ส่วนทดสอบ 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 ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. การทดสอบแบบกำหนดพารามิเตอร์ด้วย @CsvSource และ @MethodSource
  2. Mockito ขั้นสูง: ตัวจับอาร์กิวเมนต์และสายลับ
  3. ส่วนทดสอบ Spring Boot: @WebMvcTest และ @DataJpaTest
  4. Testcontainers: การทดสอบการผสานรวมกับฐานข้อมูลจริง
← กลับไปที่ Java Academy