๋๋ ์ผ๋ง์ ์คํ๋ง ์ํ๋ฆฌํฐ๋ฅผ ์ค์นํ๊ณ , ์ ์ ๋ฅผ ๋ง๋ค์ด์ ์งํ์ ํ์ ์ด ์์๋ค,. ๊ทธ๋ฆฌ๊ณ ์ค๋ ํ๋ก์ญํธ๋ฅผ ์คํ์์ผฐ๋ค. ํ์ง๋ง ๊ฒฐ๊ณผ๋ ์ฐธ๋ดํ๋ค. ๋ชจ๋ ํ ์คํธ๊ฐ ํ๋ ธ๋ค๊ณ ๋์จ๋ค๋ ๊ฒ์ ์ ์ ์์๋ค. ์ด์ํ๋ค. ๋๋ ๋ถ๋ช ... ํ์ ์ด ์๋๋ฐ.. ์๊ณ ๋ณด๋ ์คํ๋ง ์ํ๋ฆฌํฐ ์์ฒด์์ ์ ์ ๋ฅผ ๋ง๋ค๊ณ , ๊ทธ๊ฒ์ ๋ชจ๋ ํ ์คํธ ์ฝ๋์ ์ ์ฉํ๊ธฐ ๋๋ฌธ์ด๋ผ๊ณ ํ๋ค. ๊ทธ๋์ ๋์จ ์ํ์ฝ๋๊ฐ 403 (๊ถํ์ด ์๋ค)๊ฐ ๋์จ๊ฒ๋ ๊ทธ ๋๋ฌธ์ธ๊ฒ ๊ฐ๋ค. ๊ทธ๋ฌ๋ฉด ์ด๋ป๊ฒ ์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํด์ผ ๋ ๊น? @Configuration @EnableWebSecurity public class SpringConfig extends WebSecurityConfigurerAdapter{ } ์ด๊ฑธ ์ถ๊ฐํ๊ฒ ๋๋ฉด ์คํ๋ง ์ํ๋ฆฌํฐ์์ ์ ์ฉ๋๋ ์ํ๋ฆฌํฐ๋ ๋ ์ด์ ์ ..
์๋๋ ์คํ๋ง ์ํ๋ฆฌํฐ์ ๋ํด ๊ณต๋ถํ๊ณ ํ๋ ค๋ค๊ฐ ๋๋ฌด ์ค๋ ๊ฑธ๋ฆด ๊ฒ ๊ฐ์ ์๋ตํ๊ณ ์ ์ฉํ๋๊ฒ๋ถํฐ ์งํํ๋ ค๊ณ ํ๋ค. ์๋ฌดํผ ์คํ๋ง ์ํ๋ฆฌํฐ๋ฅผ ์ ์ฉํ๋ ์ด์ ๋ ๊ฒ์๊ธ์ ๋ง๋ ์ ์ ๋ง ์์ ์ด ๊ฐ๋ฅํ๊ฒ ๋ง๋ค๊ธฐ ์ํด ์ ์ฉํ๋๊ฑธ๋ก ์๊ณ ์๋ค. ์๋ฌดํผ... ์ ์ฉํด๋ณด์. org.springframework.security.oauth.boot spring-security-oauth2-autoconfigure 2.1.10.RELEASE ์ด๊ฒ์ ์ถ๊ฐํด์ค์ผ ์คํ๋ง ์ํ๋ฆฌํฐ๋ฅผ ์ฌ์ฉํ ์ ์๊ฒ ๋๋ค. (์ด๊ธ์ ๋ฐฑ๊ธฐ์ ๋ ๊ฐ์๋ฅผ ๋ณด๊ณ ์์ฑํ ๊ธ์ด๊ธฐ๋๋ฌธ์ start.security๋ฅผ ์ฌ์ฉํ์ง ๋์ง ์์ต๋๋ค.) ์๊ฐํด๋ณด๋ vo๋ฅผ ๋ง๋ค์ง ์์๋ค. @Getter @Setter @Builder @NoArgsConstructor @AllArgs..
์ด๋ฒ์๋ ๊ฐ์๋ฅผ ๋ฃ๊ธฐ์ ์ ๋จผ์ ์์ฑํ๊ธฐ๋ก ํด๋ณด์. ์ด๋ฒคํธ ์์ ์ ๊ฒฝ์ฐ๋ 1. ์์ ์ด ์ ์์ ์ผ๋ก ์คํ์ด ๋์์๋ : 200 2. ์์ ์ด ์๋ชป๋ ๊ฒฝ์ฐ - ๋น์ด์๋ ๊ฐ์ฒด๊ฐ ๋ค์ด์์ ๊ฒฝ์ฐ. - ์๋ชป๋ ๊ฐ์ฒด๊ฐ ๋ค์ด์ฌ ๊ฒฝ์ฐ.. - ๊ถํ์ด ์๋ ์ฌ๋์ด ์ ๊ทผํ์ ๊ฒฝ์ฐ - ํ์ด์ง๊ฐ ์กด์ฌํ์ง ์๋ ๊ฒฝ์ฐ ์ด๋ ๊ฒ ๋ค ์ ์๋๋ฐ... ์์งํ 2-3์ ์ง๊ธ๋น์ฅ์ ํ์ง ๋ชปํ ๊ฒ ๊ฐ๋ค. ์๋ํ๋ฉด ์ ์ ๋ฅผ ๊ณ ๋ คํ์ง ์์๊ธฐ ๋๋ฌธ์ด๋ค. ํ ์คํธ ์ฝ๋๋ฅผ ์์ฑํด๋ณด์. @Test void update_event() throws Exception { Delivery delivery = generateEvent(100); DeliveryDto deliveryDto = modelMapper.map(delivery, DeliveryDto.class); ..
๊ณง ํ์ฌ์ผ์ด ๋ฐ๋น ์ง๋ค๊ณ ํ๋ค. ๋ฐ๋น ์ง๊ธฐ ์ ์ ์ด์ฌํ ๊ณต๋ถ ํ์! ๊ฐ๋จํ๊ฒ ํ ์คํธ ๋ถํฐ ์์ฑํด๋ณด์. @Test public void create_event() throws Exception { Delivery delivery = generateEvent(100); this.mockMvc.perform(get("/api/delivery/{id}",delivery.getId())) .andDo(print()) .andExpect(status().isOk()) .andExpect(jsonPath("id").exists()) .andExpect(jsonPath("_links.self").exists()) .andExpect(jsonPath("_links.profile").exists()); } ์ด๊ฒ์ ์คํํ๋ฉด ์ด..
๋จผ์ ํ ์คํธ ์ฝ๋๋ถํฐ ์์ฑํ์. @Test void eventQuery() { IntStream.range(0, 30) .forEach(this::generateEvent); } private void generateEvent(int index) { Delivery delivery = Delivery.builder() .item("Delivery" + index) .user("klom") .build(); deliveryRepository.save(delivery); } ์ด๋ ๊ฒ ์์ฑํ๋ฉด ๋๋ 0๋ฒ๋ถํฐ 30๋ฒ๊น์ง์ ์ด๋ฒคํธ๋ฅผ ์์ฑํ๋ ๋ก์ง์ด๋ค. ๊ทธ๋ฌ๋ฉด ์๊ฐํด์ผ ๋ ๊ฒ์ด ์ด์ ์ด๊ฒ๋ค์ ํ ์คํธ๋ฅผ ํด์ผ ๋๋ค. ์ต์ข ์ฝ๋๋ ๋ค์๊ณผ ๊ฐ๋ค. @Test void eventQuery() throws Exception { I..
* ์ฌ๊ธฐ์ ์ธ๋ฑ์ค๋? ๋ฉ์ธ ํ์ด์ง๋ฅผ ๋ปํฉ๋๋ค. ๋ฉ์ธํ์ด์ง๋ฅผ ์ํ ํ ์คํธ ์ฝ๋๋ฅผ ์์ฑํ์. @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.MOCK) @AutoConfigureMockMvc @AutoConfigureRestDocs @Import(RestDocsConfiguration.class) @ActiveProfiles("test") public class IndexControllerTest { @Autowired private MockMvc mockMvc; @Test void index() throws Exception { mockMvc.perform(get("/delivery")) .andDo(print()) .andExpect(sta..
์ค๋๋ง์ ์์ฑํ๋๊ฒ ๊ฐ๋ค. ์๋ฌดํผ ๋ค์ ์์ฑํ๊ฒ ๋์ด์ ๊ธฐ์๋ค.! restAPI docs๋ฅผ ๋ง๋ค๊ธฐ ์ํด์๋ org.springframework.restdocs spring-restdocs-mockmvc test ์ด ์์กด์ฑ์ ์ถ๊ฐํด์ค์ผ ํ๋ค. RestApi ๋ง๋ค๊ธฐ - spring-rest-docs (5) ์ ๋๋์ด rest-docs๋ฅผ ์ ์ฉํ ๋๊ฐ ์๋ค. Spring REST Docs Document RESTful services by combining hand-written documentation with auto-generated snippets produced with Spring MVC Test. docs.spring.io.. b-programmer.tistory.com ์ด๊ธ์์ spring-rest..
์ ๋๋์ด rest-docs๋ฅผ ์ ์ฉํ ๋๊ฐ ์๋ค. Spring REST Docs Document RESTful services by combining hand-written documentation with auto-generated snippets produced with Spring MVC Test. docs.spring.io ์๋ private MockMvc mockMvc; @Autowired private WebApplicationContext context; @Before public void setUp() { this.mockMvc = MockMvcBuilders.webAppContextSetup(this.context) .apply(documentationConfiguration(this.re..
HATEOAS๋ ๋ฌด์์ผ๊น? Hypermedia as the Engine of Application State์ ์ฝ์๋ก ์์ฒญ์ ๋ํ ์๋ต๊ฐ์ ์ฌ์ฉ์๊ฐ ์ฌ์ดํธ๋ฅผ ๋ค๋น๊ฒ์ด์ ํ ์ ์๋ ๋งํฌ๋ค์ ๋ง๋ค์ด ํฌํจ์ํฌ ์ ์๋๋ก ํด์ฃผ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ผ๊ณ ํ๋ค. ์ด๋ฌํ ๊ธฐ๋ฅ์ ์คํ๋ง์์ ์ ๊ณตํ๊ณ ์๋ค. ๊ทธ๋์ ์คํ๋ง ํค์ดํฐ์ค์ค ๊ทธ๋ผ ํค์ดํฐ์ค์ค๋ ์ด๋ค ๊ฒ์ ํด์ค๊น? ํฌ๊ฒ 2๊ฐ์ง ๋ถ๋ถ์ผ๋ก ๋๋ ์ ์๋ค. ์ฒซ ๋ฒ์งธ๋ ๋งํฌ๋ฅผ ๋ง๋ค ์ ์๋ ๊ธฐ๋ฅ์ ์ ๊ณตํ๋ค. ๋งํฌ ๋ง๋๋ ๋ฐฉ๋ฒ : linkTo(DeliveryController.class).slash(newDelivery.getId()).toUri(); ๋งํฌ๋ฅผ ๋ง๋๋ ๋ฐฉ๋ฒ์ ์ด๊ฒ๋ง๊ณ ๋ ๋ง์๋ฐ, ๋ํ์ ์ผ๋ก linkTo๋ก ๋ง๋๋ ๋ฐฉ๋ฒ์ด ์กด์ฌํ๋ค. lonkTo๋ก uri๋ฅผ ๋ง๋ค ์ ์๊ฒ ๋..
๋ง์ฝ์ ๊ฒ์ ์กฐ๊ฑด์ ์๋ชป ์ ๋ ฅํ ๊ฒฝ์ฐ๋ ์ด๋ป๊ฒ ๋ ๊น? ์ต๋ํ ๊ฐ๋จํ๊ฒ ์์ฑํด๋ดค๋ค. ๋ง์ฝ์, ์ฃผ๋ฌธ ๋ ์ง๊ฐ ๋ฐฐ๋ฌ ์๋ฃ ๋ ์ง๋ณด๋ค ๋ฆ์ ๊ฒฝ์ฐ๋ผ๋ฉด ์ด๋ป๊ฒ ํด์ผํ ๊น? ์์งํ ๋ง์ด ๋์ง ์๋๋ค. ์ด๋ด๋๋ ์ด๋ป๊ฒ ์ฒ๋ฆฌ๋ฅผ ํด์ผํ ๊น? @Test void badRequest() throws Exception { DeliveryDto delivery = DeliveryDto.builder() .item("book") .user("klom") .deliveryTime(LocalDateTime.now().plusDays(10)) .deliveryEndTime(LocalDateTime.now()) .itemPrice(0) .build(); mockMvc.perform(post("/api/delivery/") .accept(Medi..
API๋ฅผ ๋ง๋ค๋ค๋ณด๋ฉด, ์ ๋ ฅ๊ฐ์ ์ ํํ๊ณ ์ถ์ ๊ฒฝ์ฐ๊ฐ ๋ฐ์ํฉ๋๋ค. ์๋ฅผ๋ค๋ฉด, public class Delivery { private int id; private String item; private String user; private LocalDateTime deliveryTime; private LocalDateTime deliveryEndTime; private DeliveryStatus status; private Integer itemPrice; private Integer deliveryCost; } ์ด๋ฐ ๊ฐ์ฒด๊ฐ ์๋ค๊ณ ๊ฐ์ ํด๋ด ์๋ค. ๊ทธ๋ฐ๋ฐ, id๊ฐ์ ๊ฒฝ์ฐ jpa์์ ๋ฒํธ๋ฅผ ์ ํด์ฃผ๊ณ , deliveryStatus๋ ํ์ฌ ๋ฐฐ๋ฌ์ ์งํ์ ๋ณด๊ณ ๊ฒฐ์ ๋๊ณ , deliveryCost๋ itemPrice์..
c accept,content์ ๋ํด ๋ฌด์งํ๋๊ฒ ๊ฐ๋ค. @Test void create_Delivery() throws Exception { Delivery delivery = Delivery.builder() .id(10) .item("book") .user("klom") .build(); mockMvc.perform(post("/api/delivery/") .accept(MediaTypes.HAL_JSON_VALUE) .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(delivery)) ) .andDo(print()) .andExpect(status().isCreated()); } ์ฝ๋๋ฅผ ์ด๋ ๊ฒ ์์ ํ๋ค...