๐Ÿ”ฅ TIL - Day 56

Kim Dae Hyunยท2021๋…„ 11์›” 15์ผ
0

TIL

๋ชฉ๋ก ๋ณด๊ธฐ
67/93

3์ฐจ ํ”„๋กœ์ ํŠธ ๋•Œ๋Š” Spring Rest Docs๋ฅผ ์ด์šฉํ•ด์„œ API๋ฌธ์„œ๋ฅผ ์ž๋™ํ™”ํ•ด์•ผ ํ•œ๋‹ค.
Spring Rest Docs๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ํ•„์ˆ˜๋กœ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•ด์•ผ ํ•œ๋‹ค. ํ…Œ์ŠคํŠธ๊ฐ€ ๋ชจ๋‘ ์„ฑ๊ณตํ•ด์•ผ API๋ฌธ์„œ๊ฐ€ ์ž‘์„ฑ๋˜๋Š” ๊ฒƒ์ด๋‹ค.

Spring Rest Docs๋ฅผ ๋ฐ”๋กœ ์ ์šฉํ•ด๋ณด๊ธฐ ์ „์— Spring์—์„œ ๊ฐ€์žฅ ๋งŽ์ด ์“ฐ๋Š” ํ…Œ์ŠคํŠธ ํ”„๋ ˆ์ž„์›Œํฌ์ธ Junit5์— ๋Œ€ํ•ด ์•Œ์•„๋ณด์ž.

๐Ÿ“Œ ์ผ๋‹จ ์–ด๋…ธํ…Œ์ด์…˜๋ถ€ํ„ฐ ์‚ด์ง ์•Œ์•„๋ณด์ž

@Test

  • ํ…Œ์ŠคํŠธ ๋ฉ”์„œ๋“œ ์ •์˜
  • @DisplayName ์œผ๋กœ ํ…Œ์ŠคํŠธ ๋ฉ”์„œ๋“œ์— ๋Œ€ํ•œ ์ด๋ฆ„์„ ์ •์˜ํ•  ์ˆ˜ ์žˆ๋‹ค.
  • @RepeatedTest, @ParameterizedTest, @TestFactory, @TestTemplate ์ด ๋ถ™์€ ๋ฉ”์„œ๋“œ๋„ ํ…Œ์ŠคํŠธ ๋ฉ”์„œ๋“œ๋กœ ์ทจ๊ธ‰๋œ๋‹ค. ์ผ๋‹จ ์ด๋ฆ„๋งŒ ์•Œ์•„๋‘์ž.
  • @Disabled: ํ…Œ์ŠคํŠธ ํด๋ž˜์Šค or ๋ฉ”์„œ๋“œ ๋น„ํ™œ์„ฑํ™”

@BeforeEach, @AfterEach

  • ํ…Œ์ŠคํŠธ ์ „,ํ›„๋กœ ์‹คํ–‰
  • ๊ฐ ํ…Œ์ŠคํŠธ ๋ฉ”์„œ๋“œ๊ฐ€ ์‹คํ–‰๋˜๊ธฐ ์ „,ํ›„๋กœ ๋งค๋ฒˆ ํ˜ธ์ถœ๋œ๋‹ค.

@BeforeAll, @AfterAll

  • ํ…Œ์ŠคํŠธ ์ „,ํ›„๋กœ ์‹คํ–‰
  • ํ…Œ์ŠคํŠธ ์ „,ํ›„๋กœ ๋‹จ ํ•œ ๋ฒˆ๋งŒ ํ˜ธ์ถœ๋œ๋‹ค.

@SpringBootTest

  • ๋ฌด๊ฑฐ์šด ํ…Œ์ŠคํŠธ
  • ํ•„์š”ํ•œ ๋ชจ๋“  ๋นˆ์„ IoC์— ์˜ฌ๋ ค๋†“๊ณ  ํ…Œ์ŠคํŠธ๋ฅผ ์ˆ˜ํ–‰ํ•œ๋‹ค. (ํ†ตํ•ฉ ํ…Œ์ŠคํŠธ)

@WebMvcTest

  • Controller๋ฅผ ๋Œ€์ƒ์œผ๋กœ ํ…Œ์ŠคํŠธ
  • Controller ๊ณ„์ธต์˜ ๋นˆ๋งŒ ๋นˆ์œผ๋กœ ์˜ฌ๋ฆฌ๊ณ  ์ˆ˜ํ–‰ํ•˜๋Š” ํ…Œ์ŠคํŠธ์ด๋‹ค. ๋ณดํ†ต Controller์ดํ•˜ Service๊ณ„์ธต์€ Mockingํ•ด์„œ ์‚ฌ์šฉํ•œ๋‹ค.

@ExtendWith

  • @SpringBootTest๊ฐ€ ์•„๋‹Œ @WebMvcTest์—์„œ Mockito๋ฅผ ์“ฐ๊ณ  ์‹ถ๋‹ค๋ฉด?
@WebMvcTest(TestController.class)
@ExtendWith(MockitoExtension.class)

๐Ÿ“Œ ํ…Œ์ŠคํŠธ ์‹คํ–‰์ˆœ์„œ

ํŠน์ • ์ˆœ์„œ๋ฅผ ๊ธฐ์ค€์œผ๋กœ ํ…Œ์ŠคํŠธ์˜ ์ˆœ์„œ๋ฅผ ์ง€์ •ํ•  ์ˆ˜ ์žˆ๋‹ค.

@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class TestClass {
    
    @Test
    @Order(1)
    void ํ…Œ์ŠคํŠธ1() { ... }
    
    @Test
    @Order(2)
    void ํ…Œ์ŠคํŠธ2() { ... }
}

๐Ÿ“Œ ํ…Œ์ŠคํŠธ ๋ฐ˜๋ณต์‹คํ–‰

ํ…Œ์ŠคํŠธ ๋ฉ”์„œ๋“œ๋ฅผ ๋ฐ˜๋ณตํ•ด์„œ ์‹คํ–‰ํ•ด์•ผ ํ•  ๋•Œ,

public class TestClass {
    
    @RepeatedTest(10)
    void ํ…Œ์ŠคํŠธ1() { ... }
}

๐Ÿ“Œ ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ๋ฐ›์€ ํ…Œ์ŠคํŠธ ๋ฉ”์„œ๋“œ

csv ํ˜•์‹ ๋ฐ์ดํ„ฐ๋ฅผ ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ๋ฐ›๊ธฐ

@ParameterizedTest
@CsvSource({
    "key1, 1",
    "key2, 2",
    "key3, 3",
})
void ํ…Œ์ŠคํŠธ(String key, int value) { ... }

csvํŒŒ์ผ์˜ ๋ฐ์ดํ„ฐ๋ฅผ ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ๋ฐ›๊ธฐ

@ParameterizedTest
@CsvFileSource(resources="/filename.csv")
void ํ…Œ์ŠคํŠธ(String key, int value) { ... }

์–ธ์  ๊ฐ„ ์“ธ ์ผ์ด ์žˆ์„์ง€๋„.. ?

๐Ÿ“Œ ํšŒ์›๊ฐ€์ž… ํ…Œ์ŠคํŠธ ์—ฐ์Šต

@MockBean(JpaMetamodelMappingContext.class)
@WebMvcTest(UserController.class)
@ExtendWith({MockitoExtension.class})
class UserControllerTest {

    @MockBean
    UserService userService;
    @MockBean
    UserDetailsServiceImpl userDetailsService;
    @Autowired
    MockMvc mockMvc;

    @Test
    @DisplayName("์ผ๋ฐ˜ ํšŒ์›๊ฐ€์ž… ํ…Œ์ŠคํŠธ")
    void ์ผ๋ฐ˜_ํšŒ์›๊ฐ€์ž…() throws Exception {

        // Given
        SignupRequestDto dto = SignupRequestDto.builder()
                .username("test")
                .password("password")
                .reviewer(false)
                .build();

        // When
        doReturn(new User(1L, dto.getUsername(), dto.getPassword(), UserRole.ROLE_USER, 0, new ArrayList<>()))
                .when(userService).saveUser(dto);

        Gson gson = new Gson();


        // Then
        mockMvc.perform(MockMvcRequestBuilders.post("/user/signup")
                        .contentType(MediaType.APPLICATION_JSON)
                        .content(gson.toJson(dto)))
                .andDo(print())
                .andExpectAll(
                        status().isOk(),
                        jsonPath("$.result").value("success")
                );
    }
}




์ฐธ๊ณ 
https://donghyeon.dev/junit/2021/04/11/JUnit5-%EC%99%84%EB%B2%BD-%EA%B0%80%EC%9D%B4%EB%93%9C/

profile
์ข€ ๋” ์ฒœ์ฒœํžˆ ๊นŒ๋จน๊ธฐ ์œ„ํ•ด ๊ธฐ๋กํ•ฉ๋‹ˆ๋‹ค. ๐Ÿง

0๊ฐœ์˜ ๋Œ“๊ธ€