https://github.com/GroovyArea/MyChickenBreastShop
GitHub - GroovyArea/MyChickenBreastShop: ChikenBreastShop API with Spring boot
ChikenBreastShop API with Spring boot. Contribute to GroovyArea/MyChickenBreastShop development by creating an account on GitHub.
github.com
์ ๋ฒ ์ฃผ์ ์ฒ์์ผ๋ก ๋จ์ ํ ์คํธ๋ฅผ ๊ณต๋ถํ๊ณ ์ ์ฉ์ํค๋ฉฐ Spring REST Docs๋ฅผ ์ด์ฉํด ์ ์ฉ์์ผฐ๋ค.
์ฒ์ ๋จ์ ํ ์คํธ๋ฅผ ์์ฑํ๋ค ๋ณด๋ ๋ฏธํกํ ๋ถ๋ถ์ด ์ข ์์๋ค. ๊ทธ ๋ถ๋ถ์ ์์ ํด๊ฐ๋ฉฐ ๋ค๋ฅธ ์ปจํธ๋กค๋ฌ์ ๋จ์ ํ ์คํธ๋ฅผ ์ถ๊ฐ๋ก ์์ฑํ๋ค.
API ๋ฌธ์๋ฅผ ์์ฑํ ๋๋ ํตํฉํด์ ์์ฑ ์ค์ด์๋๋ฐ, ๋๋ฉ์ธ ๋ณ๋ก ๋๋์ด ์์ ํ๋ฉฐ ์์ฑํด๋ณด์๋ค.
์ปจํธ๋กค๋ฌ๋ฅผ ๋ง์น๊ฒ ๋๋ฉด ์๋น์ค ๊ณ์ธต์ ๋จ์ ํ ์คํธ๋ ์๋ฏธ๊ฐ ์์ ๊ฒฝ์ฐ ์์ฑํด ๋ณผ ์๊ฐ์ด๋ค.
ํ ์คํธ ์ฝ๋ ์์ฑ์ด ์๋ฃ ๋๋ฉด ์ฑ๋ฅ ์ธก์ ์ ํ๋ฉฐ, ๋ฆฌํฉํฐ๋ง์ ํ ๊ณํ๋ ์๋ฆฝํ๋ค.
ํ ๋น์ ์คํ๋ง ์ฑ ์ ๊ฑฐ์ ๋ค ์ฝ์ด ๊ฐ๋๋ฐ, ์ ๋ง ์ข์ ์ฑ ๊ฐ๋ค. ์คํ๋ง์ ์ ๋๋ก ๊ณต๋ถํ๋ ์ฌ๋์๊ฒ ๋ฌด์กฐ๊ฑด ์ถ์ฒํ๊ณ ์ถ์ ์์ ์ด๋ค. ์ด๋ ต์ง๋ง ์ ํํ๊ฒ ์ดํดํ๋ฉฐ ๋ง๋ฌด๋ฆฌํ๊ณ ์ผ๋ฅธ JPA๋ฅผ ๊ณต๋ถํ๋ฉฐ ํ์ฌ ํ๋ก์ ํธ์ ์ ์ฉ์์ผ๋ณด๊ณ ์ถ๋ค.
์ฅ๋ฐ๊ตฌ๋ ์ปจํธ๋กค๋ฌ ๋จ์ ํ ์คํธ
์ ๋ฒ ์ฃผ์ ํ์, ์ํ ์ปจํธ๋กค๋ฌ์ ๋จ์ ํ ์คํธ๋ฅผ ์งํํ๋ค. ์ด๋ฒ 3์ผ๊ฐ ์งํํ ๋จ์ ํ ์คํธ๋ ๊ธฐ์กด ํ ์คํธ ์ฝ๋์ ๋ฌธ์ ์ ์ ๋ณด์ํด ์งํํ๋ค.
@BeforeEach
void setUpCookie() {
cartItemDTOMap.put(addCartDTO1.getProductNo(), addCartDTO1);
cartItemDTOMap.put(addCartDTO2.getProductNo(), addCartDTO2);
cookieList.add(cookie1);
cookieList.add(cookie2);
cookieList.add(cookie3);
cookieList.add(cookie4);
newCartCookie = new Cookie("Chicken", URLEncoder.encode(JsonUtil.objectToString(cartItemDTOMap), StandardCharsets.UTF_8));
newCartCookie.setMaxAge(60 * 60 * 24 * 7);
newCartCookie.setPath("/api");
cookieList.add(newCartCookie);
cookies = cookieList.toArray(Cookie[]::new);
}
ํ ์คํธ๋ฅผ ์คํํ ๋๋ง๋ค ๊ธฐ๋ณธ์ ์ผ๋ก ์ฟ ํค ๊ฐ์ ์ธํ ํด์ผ ํ๊ธฐ ๋๋ฌธ์ @BeforeEach๋ฅผ ์ฌ์ฉํด Setup ๋ฉ์๋๋ฅผ ๋ง๋ค์๋ค.
@Test
@DisplayName("์ฅ๋ฐ๊ตฌ๋ ์กฐํ ํ
์คํธ")
void getCartListTest() throws Exception {
Mockito.when(cartService.getCartCookie(cookies)).thenReturn(newCartCookie);
Mockito.when(cartService.getCartDTOMap(newCartCookie)).thenReturn(cartItemDTOMap);
mockMvc.perform(get("/api/carts")
.cookie(cookies))
.andExpect(status().isOk())
.andExpect(jsonPath("$[0]").exists())
.andExpect(jsonPath("$[1]").exists())
.andDo(print());
}
๊ธฐ๋ณธ์ ์ธ ์ฅ๋ฐ๊ตฌ๋ ์กฐํ ํ ์คํธ์ด๋ค. @Mockbean ๋ ์๋น์ค ๋ฉ์๋์ ๋์์ ๋จผ์ ์ ์ํ๊ณ (given) ๊ฒฐ๊ณผ ๊ฐ์ ์กด์ฌ ์ ๋ฌด๋ก ํ๋จํ๋ค(when & then).
@Test
@DisplayName("์ฅ๋ฐ๊ตฌ๋ ์ํ ์ญ์ ํ
์คํธ")
void deleteCart() throws Exception {
cartItemDTOMap.remove(deleteCartDTO.getProductNo());
cookieList.add(newCartCookie);
Mockito.when(cartService.getCartCookie(cookies)).thenReturn(newCartCookie);
Mockito.when(cartService.getCartDTOMap(newCartCookie)).thenReturn(cartItemDTOMap);
Mockito.when(cartService.resetCartCookie(newCartCookie, cartItemDTOMap)).thenReturn(newCartCookie);
mockMvc.perform(delete("/api/carts")
.cookie(cookies)
.contentType(MediaType.APPLICATION_JSON)
.content(JsonUtil.objectToString(deleteCartDTO)))
.andExpect(status().isOk())
.andExpect(content().string(ResponseMessage.DELETE_MESSAGE.getValue()))
.andDo(print());
}
๋๋จธ์ง ํ ์คํธ๋ ๊ฑฐ์ ๋น์ทํ๊ธฐ ๋๋ฌธ์ ์ญ์ ํ ์คํธ๋ ๊ฑฐ์ ๋น์ทํ ๊ตฌํ์ด๋ค.
ํ ์คํธ๋ฅผ ์ํ ํ ์์ฑ๋ snippets ํ์ผ๋ค๋ก ๋ช ์ธ๋ฅผ ๋ง๋ค์๋ค. ๋ณธ ๊ทธ๋ฆผ์ ๋๋ฉ์ธ ๋ณ๋ก ๋๋ ๋ชจ์ต์ด๋ค.
์ฃผ๋ฌธ ์ปจํธ๋กค๋ฌ ๋จ์ ํ ์คํธ
์ฃผ๋ฌธ ์ปจํธ๋กค๋ฌ๋ ์นด์นด์คํ์ด REST API๋ฅผ ์ด์ฉํด ๊ตฌํํ์๋ค. ๊ทธ๋์ ๋๊ฒจ๋ฐ๊ณ ์ค ํ๋ผ๋ฏธํฐ๋ค์ด ์์ฒญ ๋ง๋ค.
๊ทธ๋์ ์ ์ข ๋จน์๋ค. ๊ทธ๋ฆฌ๊ณ mockito์ ๊ฐ๋ ์ ๋ฆฝ์ ํ์คํ ๋ ๋ค์ ธ๊ฐ ํ ์คํธ์ด๊ธฐ๋ ํ๋ค.
@Test
@DisplayName("ํ์ ์ฃผ๋ฌธ ์กฐํ ๋ฆฌ์คํธ ํ
์คํธ")
void getDBOrderInfo() throws Exception {
List<OrderInfoDTO> orderInfoDTOList = new ArrayList<>();
orderInfoDTOList.add(orderInfoDTO);
Mockito.when(orderService.getOrderInfoList(orderInfoDTO.getPartnerUserId())).thenReturn(orderInfoDTOList);
mockMvc.perform(get("/api/order/{userId}", orderInfoDTO.getPartnerUserId())
.header("Authorization", "Bearer ${ADMIN_AUTH_TOKEN}"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.data").exists())
.andExpect(jsonPath("$.message", is("ํ์ ์ฃผ๋ฌธ ์กฐํ ๋ฆฌ์คํธ์
๋๋ค.")))
.andDo(print());
}
DB์ ์ ์ฅ๋ ์ฃผ๋ฌธ ์๋ฃ ๋ฐ์ดํฐ๋ฅผ ์กฐํํ๋ ์์ฃผ ๊ธฐ๋ณธ์ ์ธ ํ ์คํธ์ด๋ค.
@Test
@DisplayName("๋จ๊ฑด ๊ฒฐ์ ํ
์คํธ")
void orderAction() throws Exception {
String userId = orderInfoDTO.getPartnerUserId();
String url = "https://online-pay.kakao.com/mockup/v1/cd749f82c8c58decb5c832ab45a0990e02c87b07e32bf3f28aa9b9297a0cf710/info";
Mockito.when(kakaoPayService.getkakaoPayUrl(any(OrderProductDTO.class), anyString(), anyString())).thenReturn(url);
mockMvc.perform(post("/api/order")
.header("Authorization", "Bearer ${ADMIN_AUTH_TOKEN}")
.contentType(MediaType.APPLICATION_JSON)
.content(JsonUtil.objectToString(orderProductDTO))
.requestAttr("tokenUserId", userId))
.andExpect(status().isOk())
.andExpect(jsonPath("$.data", is(url)))
.andExpect(jsonPath("$.message", is("์นด์นด์ค ํ์ด ๊ฒฐ์ URL")))
.andDo(print());
}
@Test
@DisplayName("์ฅ๋ฐ๊ตฌ๋ ๊ฒฐ์ ํ
์คํธ")
void cartOrderAction() throws Exception {
given(cartService.getCartCookie(cookies)).willReturn(newCartCookie);
String userId = orderInfoDTO.getPartnerUserId();
String url = "https://online-pay.kakao.com/mockup/v1/ce3cb801e74a337fb7cf74d9a9aa139bb569e74ba316ae7eb282b90f8f08a522/info";
given(kakaoPayService.getCartKakaoPayUrl(any(Integer[].class), any(String[].class),
any(Integer[].class), anyInt(), anyString(), anyString())).willReturn(url);
mockMvc.perform(post("/api/order/cart")
.header("Authorization", "Bearer ${ADMIN_AUTH_TOKEN}")
.cookie(cookies)
.requestAttr("tokenUserId", userId))
.andExpect(status().isOk())
.andExpect(jsonPath("$.data", is(url)))
.andExpect(jsonPath("$.message", is("์นด์นด์ค ํ์ด ๊ฒฐ์ URL")))
.andDo(print());
}
์ฌ๊ธฐ์ ๋ฌธ์ ๊ฐ ์์๋ค. Mockbean ์ ์ํ ์๋น์ค ๋ฉ์๋์ ํ๋ผ๋ฏธํฐ๋ฅผ ์ฌ๋ฌ๊ฐ ๋๊ฒจ์ฃผ๋ ์ํฉ์ given์ผ๋ก ์ฃผ์ด์ผ ํ๋๋ฐ, ๊ตฌ์ฒด์ ์ธ ๋ณ์๋ฅผ ์ ์ํ์ฌ ๋ฃ์ผ๋ ๊ณ์ ๋ฉ์๋๊ฐ null์ return ํ๋ค.
์ด๋๊ฐ ์๋ชป๋์๋ ๊ณ์ ๋ณด์๊ณ , ๊ฒ์์ ํ์ฐธ ํด๋ณด๋, mockito๋ ๊ธฐ๋ณธ์ ์ผ๋ก mockbean ์ธ์คํด์ค๋ ํธ์ถ๋ json์ ์ญ์ง๋ ฌ ํํ์ฌ ์๋กญ๊ฒ ๋น๋๋ ์ธ์คํด์ค์ด๋ฏ๋ก ๊ธฐ์กด ์ธ์คํด์ค์ ์ง์์ ์๋ตํ์ง ์๋๋ค๊ณ ํ๋ค. ๊ทธ๋์
any() ๋ฉ์๋๋ฅผ ์ด์ฉํ์ฌ ์ ์์ ์ผ๋ก ๊ฐ์ ์ป๋ ๊ฒฐ๊ณผ๋ฅผ ๋ด๋ ํ ์คํธ๋ฅผ ์ฑ๊ณต์ ์ผ๋ก ์๋ฃํ๊ฒ ๋์๋ค.
Mocked method return value is null in Spring Boot @WebMvcTest
The below test fails with: org.json.JSONException: Unparsable JSON string. I tried various variations of the mocking the saveAndFlush method // doAnswer(returnsFirstArg()).when(this.
stackoverflow.com
์ถํ ์งํํ ๋จ์ ํ ์คํธ๋ ๊ฒฐ์ ์ปจํธ๋กค๋ฌ ๋จ์ ํ ์คํธ๊ฐ ๋จ์๋ค. ๋ถ์ง๋ฐํ ์์ฑํด๋ณด์~~
๊ธ์ฃผ ๊ณํ
- ํ ๋น์ ์คํ๋ง ์๋ (์ค๋ ์๋ ํด๋ณด์)
- JPA ๊ณต๋ถ ์์ (์ค๋ ์ด๊น..? ๋ด์ผ ์ฌ์)
- ์๋น์ค ๊ณ์ธต ๋จ์ ํ ์คํธ & ์ฑ๋ฅ ์ธก์ (APM ํ ์คํธ)
- ์ค์ผ์ฅด๋ฌ ์คํ (์์ธ ๋กค๋ฐฑ ์ฒ๋ฆฌ ํ ์คํธ)
- ์๋ฃ๊ตฌ์กฐ ์ ๋ฆฌ (๋ด์ผ) ๋ฐ ํด๋น ๋ฌธ์ 3๊ฐ ํ๊ธฐ
- http, ์ด์์ฒด์ ์๊ธฐ ์ ํํ์ด ์ฝ๊ธฐ
'๐ Spring Framework > Spring Project' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
์คํ๋ง ๋ถํธ ์๋ํ๋ธ(SonarQube) ์ ์ฉ + PostgreSql (0) | 2022.07.05 |
---|---|
ใํ์ผ ์ ๋ก๋/๋ค์ด๋ก๋ ๋ฐ ํ ์คํธใ (0) | 2022.07.01 |
ใํ ์คํธ ์ฝ๋ & Spring REST Docsใ (0) | 2022.06.20 |
OutBox Pattern & Saga Pattern & Transaction (0) | 2022.06.13 |
ใOutBox Patternใ ํ์ฉ (0) | 2022.06.10 |