th42500의 TIL

Given-When-Then νŒ¨ν„΄κ³Ό given()&when() λ³Έλ¬Έ

Backend/JUnit & BDD

Given-When-Then νŒ¨ν„΄κ³Ό given()&when()

th42500 2023. 1. 3. 22:59

Given - When - Then νŒ¨ν„΄

 

πŸ“– Given-When-Then νŒ¨ν„΄μ΄λž€?

ν…ŒμŠ€νŠΈ μ½”λ“œλ₯Ό ν‘œν˜„ν•˜λŠ” 방식 쀑 ν•˜λ‚˜λ‘œ, TDD(Test-Driven Development; ν…ŒμŠ€νŠΈ 주도 개발)μ—μ„œ νŒŒμƒλœ BDD(Behavior-Driven-Development; ν–‰μœ„ 주도 개발)λ₯Ό 톡해 νƒ„μƒν•œ ν…ŒμŠ€νŠΈ μ ‘κ·Ό 방식

 

1️⃣ Given

ν…ŒμŠ€νŠΈ μˆ˜ν–‰ μ „ ν…ŒμŠ€νŠΈμ— ν•„μš”ν•œ ν™˜κ²½ 섀정을 ν•˜λŠ” λ‹¨κ³„λ‘œ, ν…ŒμŠ€νŠΈμ— ν•„μš”ν•œ λ³€μˆ˜ μ •μ˜ λ˜λŠ” Mock객체λ₯Ό ν™œμš©ν•œ νŠΉμ • 상황에 λŒ€ν•œ 행동 μ •μ˜λ₯Ό ν•˜λŠ” 단계

 

2️⃣ When

ν…ŒμŠ€νŠΈμ˜ λͺ©μ μ„ λ³΄μ—¬μ£ΌλŠ” λ‹¨κ³„λ‘œ, μ‹€μ œ ν…ŒμŠ€νŠΈ μ½”λ“œλ₯Ό ν¬ν•¨ν•˜μ—¬ ν…ŒμŠ€νŠΈλ₯Ό ν†΅ν•œ 결괏값을 κ°€μ Έμ˜€λŠ” 단계

 

3️⃣ Then

ν…ŒμŠ€νŠΈ κ²°κ³Όλ₯Ό κ²€μ¦ν•˜λŠ” λ‹¨κ³„λ‘œ, When 단계 λ˜λŠ” ν…ŒμŠ€νŠΈλ₯Ό 톡해 λ‚˜μ˜¨ κ²°κ³Ό 쀑 검증이 ν•„μš”ν•œ 뢀뢄에 λŒ€ν•΄ 검증

 

 

πŸ“Œ given()κ³Ό when() λ©”μ„œλ“œ

given()

Mokitoμ—μ„œ μ œκ³΅ν•˜λŠ” given() λ©”μ„œλ“œλ₯Ό 톡해 μ–΄λ–€ κ°μ²΄μ—μ„œ, μ–΄λ–€ λ©”μ„œλ“œκ°€ 호좜되고 μ–΄λ–€ νŒŒλΌλ―Έν„°λ₯Ό μ£Όμž… λ°›λŠ”μ§€ κ°€μ •ν•œ ν›„ willReturn() λ˜λŠ” willThrow() 등을 μ΄μš©ν•˜μ—¬ κ²°κ³Όλ₯Ό 미리 μ •μ˜ν•΄λ†“κΈ° μœ„ν•΄ μ‚¬μš©

@WebMvcTest
class UserRestControllerTest {

    @Autowired
    private MockMvc mockMvc;
    @Autowired
    private ObjectMapper objectMapper;

    @MockBean
    UserService userService;

    @Test
    @DisplayName("getUser ν…ŒμŠ€νŠΈ")
    void getUserTest() throws Exception {
        given(userService.getUser(1L)).willReturn(new UserResponseDto(1L, "user", "μœ μ € μ°ΎκΈ° 성곡"));

        Long userId = 1L;

        mockMvc.perform(get(String.format("/api/v1/users/%d", userId)))
                .andExpect(status().isOk())
                .andExpect(jsonPath("$.id").exists())
                .andExpect(jsonPath("$.username").value("user"))
                .andExpect(jsonPath("$.message").value("μœ μ € μ°ΎκΈ° 성곡"))
                .andDo(print());

        verify(userService).getUser(1L);
    }
}

 

when()

ν…ŒμŠ€νŠΈμ— μ‚¬μš©λ  μ—”ν‹°ν‹° 객체λ₯Ό μƒμ„±ν•œ ν›„, when() λ©”μ„œλ“œλ₯Ό 톡해 μ–΄λ–€ λ©”μ„œλ“œκ°€ 호좜되고 μ–΄λ–€ νŒŒλΌλ―Έν„°λ₯Ό μ£Όμž… λ°›λŠ”μ§€ κ°€μ •ν•œ ν›„ thenReturn() λ©”μ„œλ“œλ₯Ό μ΄μš©ν•˜μ—¬ λ™μž‘μ— λŒ€ν•œ 결괏값 리턴을 μ„€μ •ν•˜κΈ° μœ„ν•΄ μ‚¬μš©

@WebMvcTest
class UserRestControllerTest {

    @Autowired
    private MockMvc mockMvc;
    @Autowired
    private ObjectMapper objectMapper;

    @MockBean
    UserService userService;

    @Test
    @DisplayName("getUser ν…ŒμŠ€νŠΈ")
    void getUserTest() throws Exception {
        when(userService.getUser(1L)).thenReturn(new UserResponseDto(1L, "user", "μœ μ € μ°ΎκΈ° 성곡"));

        Long userId = 1L;

        mockMvc.perform(get(String.format("/api/v1/users/%d", userId)))
                .andExpect(status().isOk())
                .andExpect(jsonPath("$.id").exists())
                .andExpect(jsonPath("$.username").value("Soyeong"))
                .andExpect(jsonPath("$.message").value("μœ μ € μ°ΎκΈ° 성곡"))
                .andDo(print());

        verify(userService).getUser(1L);
    }
}

 

 

❓ Given-given(), When-when() λ™μΌν•œ μ—­ν• μΌκΉŒ?

닡은 ❌ 이닀.

μ•žμ„œ μ„€λͺ…ν•œ 바와 같이 given() κ³Ό when() λͺ¨λ‘ Given-When-Then 쀑 Given의 역할을 λ‹΄λ‹Ήν•˜λŠ” λ©”μ„œλ“œλ‘œ, μ–΄λ– ν•œ λ©”μ„œλ“œκ°€ 호좜되고 μ–΄λ–€ νŒŒλΌλ―Έν„°λ₯Ό μ£Όμž…λ°›λŠ”μ§€ κ°€μ •ν•œ ν›„ 이에 λŒ€ν•œ 결괏값을 미리 μ •μ˜ν•˜κΈ° μœ„ν•΄ μ‚¬μš©ν•œλ‹€.

λ‹€λ§Œ, given()의 경우 willReturn(), willThrow() λ“±μ˜ λ©”μ„œλ“œλ‘œ 결괏값을 μ •μ˜ν•  수 있고 when()의 경우 thenReturn(), thenThrow() λ“±μ˜ λ©”μ„œλ“œλ‘œ 결괏값을 μ •μ˜ν•  수 μžˆλ‹€λŠ” 차이점이 μžˆλ‹€.

'Backend > JUnit & BDD' μΉ΄ν…Œκ³ λ¦¬μ˜ λ‹€λ₯Έ κΈ€

MockTest μ‹œ null 값이 λœ¨λŠ” 이유  (0) 2023.01.26
[JUnit] @Nestedλž€?  (0) 2023.01.04
[Test] MockTest 쀑 λ°œμƒν•œ 401 (Unauthorized) μ—λŸ¬  (0) 2023.01.01
Comments