๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
๐Ÿ™‚์ฃผ์ธ์žฅ ํšŒ๊ณ ๋ก

์ฝ”๋“œ์ˆจ ์Šคํ”„๋ง [15๊ธฐ] - 5์ฃผ์ฐจ ํšŒ๊ณ 

by MuGeon Kim 2023. 3. 12.
๋ฐ˜์‘ํ˜•

1. ์ด๋ฒˆ ์ฃผ์— ํ•™์Šตํ•œ ๋‚ด์šฉ

  • ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ์— ๋Œ€ํ•ด ํ•™์Šต์„ ํ•˜์˜€๋‹ค.
  • DTO์— ๋Œ€ํ•ด ํ•™์Šต
  • Dozer๋ฅผ ์ด์šฉํ•œ ๋” ํŽธํ•œ Mapping
  • Test Code

 

2. ์ค‘์ ์ ์œผ๋กœ ํ•™์Šตํ•œ ๋ถ€๋ถ„

  • ๊ฐ•์˜์™€ ๋ฆฌ๋ทฐ๋ฅผ ํ†ตํ•˜์—ฌ ์ด์ œ ์ข‹์€ ์ฝ”๋“œ์˜ ํ‹€์„ ์•Œ๊ธฐ ์‹œ์ž‘ํ–ˆ๋‹ค. ๊ธฐ์กด์— ๋‚ด๊ฐ€ ์ž‘์„ฑํ•˜๋Š” ๋ฐฉ์‹๊ณผ ๋„ˆ๋ฌด ๋‹ฌ๋ผ ์•„์ง ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๋ฉด์„œ ๋ฏธ์ˆ™ํ•œ ๋ถ€๋ถ„์ด ๋งŽ์•˜๋‹ค. ๊ทธ๋ž˜์„œ ์ด๋ฒˆ ์ฃผ๋Š” ์ง€๊ธˆ๊นŒ์ง€ ๋”ฑ ๋ฐฐ์šด ๋ถ€๋ถ„์„ ๋งŽ์ด ์ž‘์„ฑ์„ ํ•ด๋ณด์ž ์ƒ๊ฐ์„ ํ•˜์˜€๊ณ  ๊ฐ•์˜๋ฅผ ๋งŽ์ด ๋ณด๊ณ  ์ฝ”๋“œ์— ๋Œ€ํ•ด ์ƒ๊ฐํ•˜๋Š” ์‹œ๊ฐ„์„ ๊ฐ€์กŒ๋‹ค. ์ฝ”๋“œ๋ฅผ ์™œ ์ด๋ ‡๊ฒŒ ์ž‘์„ฑ์„ ํ–ˆ์„๊นŒ ์ƒ๊ฐ์„ ํ•ด๋ณด๋ฉด์„œ ๋” ๊ณต๋ถ€ํ•ด์•ผ ๋˜๋Š” ๋‚ด์šฉ๋“ค์ด ์ƒ๊ฒผ๋‹ค.

 

  • HTTP Status์— ๋Œ€ํ•ด์„œ ๋‹ค์‹œ ๊ณต๋ถ€๋ฅผ ํ•˜๊ฒŒ ๋˜์—ˆ๋‹ค. ๊ธฐ์กด์— ๋‚ด๊ฐ€ ์•Œ๊ณ  ์žˆ๋Š” ๋‚ด์šฉ์œผ๋กœ ๋กœ์ง์ด ์„ฑ๊ณตํ•˜๋ฉด status_code๋Š” OK(200)์„ ๋„˜๊ฒจ์ค€๋‹ค๊ณ  ์ƒ๊ฐ์„ ํ–ˆ๋‹ค. ํ•˜์ง€๋งŒ Mapping()๋งˆ๋‹ค ๊ทธ ๊ธฐ์ค€์ด ๋‹ค๋ฅด๋‹ค๋Š” ๊ฑธ ์•Œ๊ฒŒ ๋˜์–ด์„œ ๋‹ค์‹œ ํ•™์Šตํ•˜๊ณ  ์žˆ๋‹ค.

 

  • ๊ธฐ๋ณธ๊ธฐ์— ์ถฉ์‹คํ•˜์ž Dozer๋ฅผ ํ†ตํ•˜์—ฌ ํŽธํ•˜๊ฒŒ Mapping์ด ๊ฐ€๋Šฅํ–ˆ๋‹ค. ํ•˜์ง€๋งŒ ์•„์ง ๊ธฐ๋ณธ์ ์ธ Builder์— ๋Œ€ํ•ด ๋ถ€์กฑํ•œ ๋ถ€๋ถ„์ด ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•˜์—ฌ Dozer๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š์•˜๋‹ค. ๋‹ค์–‘ํ•œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉ์„ ํ•˜๋ฉด ๋ฌผ๋ก  ํŽธํ•˜๊ฒ ์ง€๋งŒ ๊ฐœ๋ฐœ์ž๋ผ๋ฉด ๊ธฐ๋ณธ์ด ๋จผ์ € ๊ฐ€๋Šฅํ•ด์•ผ ๋œ๋‹ค๊ณ  ์ƒ๊ฐํ•œ๋‹ค. ๋Œ€ํ‘œ์ ์ธ ์˜ˆ๋กœ Jackson์ด ์žˆ๋‹ค. RestApi๋ฅผ ๋งŒ๋“ค๋ฉด์„œ ํ•ญ์ƒ ์‚ฌ์šฉํ•˜๋Š” Jackson์— ๋Œ€ํ•ด์„œ๋„ ์ž์„ธํ•˜๊ฒŒ ์•Œ์ง€ ๋ชปํ–ˆ๋‹ค. ControllerAdvice์—์„œ status ์ฝ”๋“œ์™€ ๋ฉ”์‹œ์ง€๋ฅผ ์ „๋‹ฌํ•˜๋Š” ์˜ˆ์™ธ๋ฅผ ๋งŒ๋“ค์–ด ํ…Œ์ŠคํŠธ๋ฅผ ํ•ด๋ณด๋‹ˆ ์ƒ์„ฑ์ž ์˜ค๋ฅ˜๊ฐ€ ์ƒ๊ฒผ๋‹ค. ์•Œ๊ณ  ๋ณด๋‹ˆ๊น Builder๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด์„œ ์ „์ฒด ์ƒ์„ฑ์ž๋Š” ๋งŒ๋“ค์—ˆ์ง€๋งŒ ๊ธฐ๋ณธ ์ƒ์„ฑ์ž๊ฐ€ ์—†์–ด์„œ ์ƒ๊ธด ์˜ค๋ฅ˜์ธ๋ฐ ๊ทธ ์ด์œ ๊ฐ€ Jackson์ด DTO๋ฅผ ํ˜ธ์ถœํ•˜๊ณ  ์—ญ ์ง๋ ฌํ™”๋ฅผ ํ•˜๋Š” ๊ณผ์ •์—์„œ ๊ธฐ๋ณธ ์ƒ์„ฑ์ž๊ฐ€ ์—†๊ธฐ ๋•Œ๋ฌธ์— ๋ฐœ์ƒํ•œ ๋ฌธ์ œ์ธ๋ฐ ์ด๋Ÿฌํ•œ ๊ธฐ๋ณธ์ ์ธ ์‹ค์ˆ˜๋ฅผ ๋ณด๊ณ  ๊ธฐ๋ณธ๊ธฐ์— ์ค‘์š”์„ฑ์„ ๋‹ค์‹œ ํ•œ๋ฒˆ ๋Š๋ผ๊ฒŒ ๋˜์—ˆ๋‹ค.
        mockMvc.perform(post("/user")
                .contentType(APPLICATION_JSON)
                .content(new ObjectMapper().writeValueAsString(user)))
                .andExpect(status().isBadRequest())
                .andExpect(jsonPath("$.message").value("์ž˜๋ชป๋œ ์ž…๋ ฅ์œผ๋กœ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒ."))
                .andExpect(jsonPath("$.code").value("400"))
                .andExpect(jsonPath("$.validation.email").value("์ด๋ฉ”์ผ์„ ์ž…๋ ฅํ•˜์„ธ์š”"))
                .andDo(print());

3. ๋Š๋‚€์ 

ํ•ญ์ƒ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๋ฉด์„œ ๋‚ด๊ฐ€ ํ‹€๋ฆฐ ๋ฐฉํ–ฅ์œผ๋กœ ์ž‘์„ฑ์„ ํ•˜๊ณ  ์žˆ๋‹ค๊ณ  ์ƒ๊ฐ์„ ํ–ˆ๋Š”๋ฐ ์ด์ œ๋Š” ์–ด๋–ป๊ฒŒ ์ž‘์„ฑํ•˜๋Š”๊ฒŒ ์ข‹์€ ์ฝ”๋“œ์˜ ํ‹€??์„ ๋Œ€์ถฉ์€ ์•Œ๊ฒ ๋‹ค. ํ•˜์ง€๋งŒ ์•„์ง ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๋Š”๊ฒŒ ์ œ์ผ ์–ด๋ ต๋‹ค. ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋ฅผ ํ†ตํ•˜์—ฌ ๋กœ์ง์„ ์ž‘์„ฑ์„ ํ•˜๋ ค๊ณ  ํ•˜๋‹ˆ ๋„ˆ๋ฌด ์–ด๋ ค์› ๋‹ค. ๋ถ„๋ช… ์ง์ ‘ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๋ฉด ๋น ๋ฅด๊ฒŒ ๋๋‚˜์ง€๋งŒ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋ฅผ ๋จผ์ € ์ž‘์„ฑํ•˜๊ณ  ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๋‹ˆ ์‹œ๊ฐ„์ด ๋” ๋งŽ์ด ๊ฑธ๋ ธ๋‹ค. ํ•˜์ง€๋งŒ ์ด๋ ‡๊ฒŒ ์–ด๋ ต๊ฒŒ ๋Š๋ผ๋ฉด์„œ ๊ณ ํ†ต์„ ๋ฐ›๋Š”๊ฑธ ๋ณด๋ฉด ์กฐ๊ธˆ์”ฉ์ด๋‚˜๋งˆ ์„ฑ์žฅ์„ ํ•˜๊ณ  ์žˆ๋‹ค๊ณ  ๋ฏฟ๊ณ ์žˆ๋‹ค. ์ง€๊ธˆ์€ ํž˜๋“ค๊ฒŒ ์ž‘์„ฑ์„ ํ•˜๊ณ  ์žˆ์ง€๋งŒ ๊พธ์ค€ํžˆ TDD์— ๋Œ€ํ•ด ์—ฐ์Šตํ•œ๋‹ค๋ฉด ์ž˜ํ• ์ˆ˜ ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•œ๋‹ค.

๋ฐ˜์‘ํ˜•