rlaguswhd19
@rlaguswhd191442
Reviews Written
-
Average Rating
-
Posts
Q&A
SpringSecurity์ loadUserbyUsername์ ๊ตฌํํ ๋ ์ง๋ฌธ์ด ์์ต๋๋ค.
๋ฆฌ์์ค ์๋ฒ์์ ๋ก๊ทธ์ธ ํ์ด์ง๋ฅผ front์๋ฒ๋ก ๋ฆฌ๋ค์ด๋ ํธ ํ๊ฒฝ์ฐ ํ๋ก ํธ์์ email๊ณผ password์ ๊ฒ์ฆ์ ์ด๋ค ๋ฐฉ์์ผ๋ก ํด์ผ๋ ์ง ๊ณ ๋ฏผ์ ๋๋ค. ๋ก๊ทธ์ธ ํ์ด์ง๋ฅผ ์ปค์คํ ํ์ง ์์์๋๋ spring security์์ ๋ด๋ถ์ ์ผ๋ก ๊ฒ์ฆ์ ํ๋๊ฒ์ด๋ผ๊ณ ์๊ฐํ๊ณ ์์ต๋๋ค. loadUserByUsername์ email๋ก db์์ ๋ถ๋ฌ์ค๋๋ฐ ๊ทธ์ ์ db์ ์๋ ์ ์ ์ password์ ์ ๋ ฅํ password๊ฐ ์ผ์นํ๋์ง์ ๋ํ ๊ฒ์ฆ์ ์ด๋ป๊ฒ ํด์ผ ํ ๊น์? api ์๋ฒ์ email๊ณผ password๋ฅผ ๋ณด๋ด์ ๊ฒ์ฆ์ ํ๋ค์ ํ ํฐ์ ๋ฐ์์์ผ ํ๋๊ฑด๊ฐ์? ์ง๊ธ ์ด์ํ๋ก ์ธ์ฆ์๋ฒ์ email๊ณผ password๋ฅผ ๋ณด๋ด๋ฉด password๊ฐ ํ๋ ค๋ ํ ํฐ์ด ๋ฐ์์ง๊ฒ ๊ฐ์์ ์ง๋ฌธ ํ์ต๋๋ค!!
- 0
- 2
- 691
Q&A
h2๋ฅผ ์ฌ์ฉํ์ฌ test๋ฅผ ์งํํ ๋ ํ๊ธ์ด ๋ค์ด๊ฐ๋ฉด h2๋ฐ์ดํฐ๊ฐ ๊นจ์ ธ์ ๋์ต๋๋ค...
์ ์ฅ๋ ํด๊ฒฐ์ ํ์ต๋๋ค. controller์์ produce๋ถ๋ถ์ produces = MediaTypes.HAL_JSON_VALUE+";charset=UTF-8" ์ด๋ผ๊ณ ์ค์ ํด์ฃผ์๋๋ ๊ฒฐ๊ณผ๊ฐ ํ๊ธ์ด ๊นจ์ง์ง ์์ต๋๋ค. ๊ทผ๋ฐ ์ ์ด์ ๊ทธ๋ผ MediaTyoes์ utf-8์ฝ๋ฉ์ด ๋์ด์๋๊ฑด ์๋๊ฑด๊ฐ์. ๊ฐ์๋ฅผ ๋ณผ๋๋ ์ฐ์ ๊ธฐ์ต์ด ์์ต๋๋ค. Hateoas๋ฒ์ ผ์ด ์ฌ๋ผ๊ฐ์ ์ฌ๋ผ์ง๊ฑด์ง ์๋๊ฑฐ๊ฐ์ต๋๋ค.
- 0
- 4
- 1.8K
Q&A
h2๋ฅผ ์ฌ์ฉํ์ฌ test๋ฅผ ์งํํ ๋ ํ๊ธ์ด ๋ค์ด๊ฐ๋ฉด h2๋ฐ์ดํฐ๊ฐ ๊นจ์ ธ์ ๋์ต๋๋ค...
https://github.com/rlaguswhd19/Screening_Clinic RESTAPI๋ฅผ ๋ณต์ตํ๋ ค๊ณ ๊ณต๊ณต๋ฐ์ดํฐ ํฌํธ์ ์ ๋ณ์ง๋ฃ์ csvํ์ผ์ ์ฌ์ฉํ์ฌ ๊ตฌํ์ค์์์ต๋๋ค. Test๋ฅผ ๋๋ฆด๋๋ Doprintํ๊ฐ์ ๊นจ์ง์ง๋ง snippet์ ํ๊ธ์ด ์ ๋๋ก ๋ค์ด๊ฐ๋๋ค. ํ์ง๋ง mvn package๋ฅผํ๊ณ snippet์ ๋ณด๋ฉด ํ๊ธ์ด ๊นจ์ ธ์์ต๋๋ค. print๋ก ์ฐ์ด๋ดค์๋ csvํ์ผ์์ ๊ธ์๊ฒ์ด ํ๊ธ๋ก ์ ๋์ต๋๋ค.
- 0
- 4
- 1.8K
Q&A
EventControllerTest์์ ์ฌ๋ฌ Test๊ฐ ๊นจ์ง๋๋ค. ๋ถํ๋๋ฆฝ๋ค..ใ ใ
์ ์ฅ๋ ๊ฐ์ฌํฉ๋๋ค. ใ ใ
- 0
- 5
- 455
Q&A
EventControllerTest์์ ์ฌ๋ฌ Test๊ฐ ๊นจ์ง๋๋ค. ๋ถํ๋๋ฆฝ๋ค..ใ ใ
https://github.com/rlaguswhd19/Spring_RestAPI์ ๋๋ค.
- 0
- 5
- 455
Q&A
EventControllerTest์์ ์ฌ๋ฌ Test๊ฐ ๊นจ์ง๋๋ค. ๋ถํ๋๋ฆฝ๋ค..ใ ใ
package com.hj.spring.events; import static org.springframework.restdocs.headers.HeaderDocumentation.headerWithName; import static org.springframework.restdocs.headers.HeaderDocumentation.requestHeaders; import static org.springframework.restdocs.headers.HeaderDocumentation.responseHeaders; import static org.springframework.restdocs.hypermedia.HypermediaDocumentation.linkWithRel; import static org.springframework.restdocs.hypermedia.HypermediaDocumentation.links; import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document; import static org.springframework.restdocs.payload.PayloadDocumentation.fieldWithPath; import static org.springframework.restdocs.payload.PayloadDocumentation.relaxedResponseFields; import static org.springframework.restdocs.payload.PayloadDocumentation.requestFields; import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.httpBasic; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put; import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; import java.time.LocalDateTime; import java.util.Set; import java.util.stream.IntStream; import org.junit.Before; import org.junit.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.hateoas.MediaTypes; import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; import org.springframework.security.oauth2.common.util.Jackson2JsonParser; import org.springframework.test.web.servlet.ResultActions; import com.hj.spring.accounts.Account; import com.hj.spring.accounts.AccountRepository; import com.hj.spring.accounts.AccountRole; import com.hj.spring.accounts.AccountService; import com.hj.spring.common.AppProperties; import com.hj.spring.common.BaseControllerTest; import com.hj.spring.common.TestDescription; public class EventControllerTest extends BaseControllerTest{ @Autowired private EventRepository eventRepository; @Autowired private AccountService accountService; @Autowired private AccountRepository accountRepository; @Autowired private AppProperties appProperties; @Before public void setUp() { this.accountRepository.deleteAll(); this.eventRepository.deleteAll(); } @Test @TestDescription("์ ์์ ์ผ๋ก ์ด๋ฒคํธ๋ฅผ ์์ฑํ๋ ํ ์คํธ") public void createEvent() throws Exception { EventDto eventDto = EventDto.builder() .name("Srping") .description("Spring API Development with Spring") .beginEnrollmentDateTime(LocalDateTime.of(2020, 02, 19, 14, 19)) .closeEnrollmentDateTime(LocalDateTime.of(2020, 02, 20, 14, 19)) .beginEventDateTime(LocalDateTime.of(2020, 02, 21, 14, 19)) .endEventDateTime(LocalDateTime.of(2020, 02, 22, 14, 19)) .basePrice(100) .maxPrice(200) .limitOfEnrollment(100) .location("Daejeon") .build(); mockMvc.perform(post("/api/events/") .header(HttpHeaders.AUTHORIZATION, getBearerToken(true)) .contentType(MediaType.APPLICATION_JSON_UTF8) .accept(MediaTypes.HAL_JSON) .content(objectMapper.writeValueAsString(eventDto)) ) .andDo(print()) .andExpect(status().isCreated()) .andExpect(jsonPath("id").exists()) .andExpect(header().exists(HttpHeaders.LOCATION)) .andExpect(header().string(HttpHeaders.CONTENT_TYPE, MediaTypes.HAL_JSON_VALUE)) .andExpect(jsonPath("free").value(false)) .andExpect(jsonPath("offline").value(true)) .andExpect(jsonPath("eventStatus").value(EventStatus.DRAFT.name())) .andExpect(jsonPath("_links.self").exists()) .andExpect(jsonPath("_links.query-events").exists()) .andExpect(jsonPath("_links.update-event").exists()) .andDo(document("create-event", links( linkWithRel("self").description("link to self"), linkWithRel("query-events").description("link to query-events"), linkWithRel("update-event").description("link to update an existing"), linkWithRel("profile").description("link to profile") ), requestHeaders( headerWithName(HttpHeaders.ACCEPT).description("accept header"), headerWithName(HttpHeaders.CONTENT_TYPE).description("content type header") ), requestFields( fieldWithPath("name").description("Name of new event"), fieldWithPath("description").description("Description of new event"), fieldWithPath("beginEnrollmentDateTime").description("BeginEnrollmentDateTime of new event"), fieldWithPath("closeEnrollmentDateTime").description("CloseEnrollmentDateTime of new event"), fieldWithPath("beginEventDateTime").description("BeginEventDateTime of new event"), fieldWithPath("endEventDateTime").description("EndEventDateTime of new event"), fieldWithPath("location").description("Location of new event"), fieldWithPath("basePrice").description("BasePrice of new event"), fieldWithPath("maxPrice").description("MaxPrice of new event"), fieldWithPath("limitOfEnrollment").description("LimitOfEnrollment of new event") ), responseHeaders( headerWithName(HttpHeaders.LOCATION).description("location header"), headerWithName(HttpHeaders.CONTENT_TYPE).description("content type header") ), //requestFields๋ฅผ ์ฌ์ฉํ๋ฉด links๊ฐ ๊ฑธ๋ฆฐ๋ค. ๋ฌธ์ํํ์ง ์์๊ธฐ ๋๋ฌธ์ด๋ค. ํ์ง๋ง relaxed๋ฅผ ์ฌ์ฉํ๋ฉด ๋ชจ๋ ๊ฒ์ ๋ฌธ์ํํ์ง ์์๋๋๋ค. //๋จ์ ์ ์ ํํ ๋ฌธ์๋ฅผ ๋ง๋ค์ง ๋ชปํ๋ค๋๊ฑฐ๋ค. //api๊ฐ ๋ฐ๊ผ์๋ ๋ชจ๋ ๊ฒ์ ๋ค ํ์ง์์ผ๋ฉด api๋ฌธ์ํ๊ฐ ์ ๋๋ก ๋์ง ์๋๋ค. relaxedResponseFields( fieldWithPath("id").description("Id of new event"), fieldWithPath("name").description("Name of new event"), fieldWithPath("description").description("Description of new event"), fieldWithPath("beginEnrollmentDateTime").description("BeginEnrollmentDateTime of new event"), fieldWithPath("closeEnrollmentDateTime").description("CloseEnrollmentDateTime of new event"), fieldWithPath("beginEventDateTime").description("BeginEventDateTime of new event"), fieldWithPath("endEventDateTime").description("EndEventDateTime of new event"), fieldWithPath("location").description("Location of new event"), fieldWithPath("basePrice").description("BasePrice of new event"), fieldWithPath("maxPrice").description("MaxPrice of new event"), fieldWithPath("limitOfEnrollment").description("LimitOfEnrollment of new event"), fieldWithPath("free").description("Free of new event"), fieldWithPath("offline").description("Offline of new event"), fieldWithPath("eventStatus").description("EventStatus of new event"), fieldWithPath("_links.self.href").description("link to self"), fieldWithPath("_links.query-events.href").description("link to query-event list"), fieldWithPath("_links.update-event.href").description("link to update existing event"), fieldWithPath("_links.profile.href").description("link to profile") ) )) ; } @Test @TestDescription("์ ๋ ฅ ๋ฐ์ ์ ์๋ ๊ฐ์ ์ฌ์ฉํ ๊ฒฝ์ฐ์ ์๋ฌ๊ฐ ๋ฐ์ํ๋ ํ ์คํธ") public void createEvent_Bad_Request_Unknown_Input() throws Exception { Event event = Event.builder() .id(100) .name("Srping") .description("REST API Development with Spring") .beginEnrollmentDateTime(LocalDateTime.of(2020, 02, 19, 14, 19)) .closeEnrollmentDateTime(LocalDateTime.of(2020, 02, 20, 14, 19)) .beginEventDateTime(LocalDateTime.of(2020, 02, 21, 14, 19)) .endEventDateTime(LocalDateTime.of(2020, 02, 22, 14, 19)) .basePrice(100) .maxPrice(200) .limitOfEnrollment(100) .location("๋์ ํ์ง์ ๋ฌ๋ธํ์ฐ์ค") .eventStatus(EventStatus.PUBLISHED) .free(true) .offline(false) .build(); mockMvc.perform(post("/api/events/") .header(HttpHeaders.AUTHORIZATION, getBearerToken(true)) .contentType(MediaType.APPLICATION_JSON_UTF8) .accept(MediaTypes.HAL_JSON) .content(objectMapper.writeValueAsString(event)) ) .andDo(print()) .andExpect(status().isBadRequest()) ; } @Test @TestDescription("์ ๋ ฅ๊ฐ์ด ๋น์ด์๋ ๊ฒฝ์ฐ์ ์๋ฌ๊ฐ ๋ฐ์ํ๋ ํ ์คํธ") public void createEvent_Bad_Request_Empty_Input() throws Exception { EventDto eventDto = EventDto.builder().build(); mockMvc.perform(post("/api/events/") .header(HttpHeaders.AUTHORIZATION, getBearerToken(true)) .contentType(MediaType.APPLICATION_JSON_UTF8) .accept(MediaTypes.HAL_JSON) .content(objectMapper.writeValueAsString(eventDto)) ) .andExpect(status().isBadRequest()) .andDo(print()) .andExpect(jsonPath("_links.index").exists()) ; } @Test @TestDescription("์ ๋ ฅ ๊ฐ์ด ์๋ชป๋ ๊ฒฝ์ฐ์ ์๋ฌ๊ฐ ๋ฐ์ํ๋ ํ ์คํธ") public void createEvent_Bad_Request_Wrong_Input() throws Exception { EventDto eventDto = EventDto.builder() .name("Srping") .description("REST API Development with Spring") .beginEnrollmentDateTime(LocalDateTime.of(2020, 02, 22, 14, 19)) .closeEnrollmentDateTime(LocalDateTime.of(2020, 02, 21, 14, 19)) .beginEventDateTime(LocalDateTime.of(2020, 02, 20, 14, 19)) .endEventDateTime(LocalDateTime.of(2020, 02, 19, 14, 19)) .basePrice(10000) .maxPrice(200) .limitOfEnrollment(100) .location("๋์ ํ์ง์ ๋ฌ๋ธํ์ฐ์ค") .build(); mockMvc.perform(post("/api/events/") .header(HttpHeaders.AUTHORIZATION, getBearerToken(true)) .contentType(MediaType.APPLICATION_JSON_UTF8) .accept(MediaTypes.HAL_JSON) .content(objectMapper.writeValueAsString(eventDto)) ) .andDo(print()) .andExpect(status().isBadRequest()) .andExpect(jsonPath("content.[0].objectName").exists()) .andExpect(jsonPath("content.[0].defaultMessage").exists()) .andExpect(jsonPath("content.[0].code").exists()) .andExpect(jsonPath("_links.index").exists()) ; } @Test @TestDescription("30๊ฐ์ ์ด๋ฒคํธ๋ฅผ 10๊ฐ์ฉ ์กฐํํ๋๋ฐ 11~20 ์กฐํํ๊ธฐ") public void queryEvent() throws Exception{ // Given IntStream.range(1, 31).forEach(i -> { this.generatedEvent(i); }); this.mockMvc.perform(get("/api/events/") .param("page", "1") .param("size", "10") .param("sort", "id,DESC") ) .andDo(print()) .andExpect(status().isOk()) .andExpect(jsonPath("page").exists()) .andExpect(jsonPath("_embedded.eventList[0]._links.self").exists()) .andExpect(jsonPath("_links.self").exists()) .andExpect(jsonPath("_links.profile").exists()) .andDo(document("query-events")) ; } @Test @TestDescription("30๊ฐ์ ์ด๋ฒคํธ๋ฅผ 10๊ฐ์ฉ ์กฐํํ๋๋ฐ 11~20 ์กฐํํ๊ธฐ With Authentication") public void queryEventWithAuthentication() throws Exception{ // Given IntStream.range(1, 31).forEach(i -> { this.generatedEvent(i); }); this.mockMvc.perform(get("/api/events/") .header(HttpHeaders.AUTHORIZATION, getBearerToken(true)) .param("page", "1") .param("size", "10") .param("sort", "id,DESC") ) .andDo(print()) .andExpect(status().isOk()) .andExpect(jsonPath("page").exists()) .andExpect(jsonPath("_embedded.eventList[0]._links.self").exists()) .andExpect(jsonPath("_links.self").exists()) .andExpect(jsonPath("_links.profile").exists()) .andExpect(jsonPath("_links.create-event").exists()) .andDo(document("query-events")) ; } @Test @TestDescription("๊ธฐ์กด์ ์ด๋ฒคํธ ํ๋ ์กฐํํ๊ธฐ") public void getEvent() throws Exception { // Given Account account = this.createAccount(); Event event = this.generatedEvent(100, account); // When this.mockMvc.perform(get("/api/events/"+event.getId())) .andExpect(status().isOk()) .andDo(print()) .andExpect(jsonPath("id").exists()) .andExpect(jsonPath("name").exists()) .andExpect(jsonPath("_links.self").exists()) .andExpect(jsonPath("_links.profile").exists()) .andDo(document("get-an-event")) ; } @Test @TestDescription("์๋ ์ด๋ฒคํธ๋ฅผ ์กฐํํ์๋ 404์๋ต๋ฐ๊ธฐ") public void getEvent404() throws Exception { // When this.mockMvc.perform(get("/api/events/123")) .andExpect(status().isNotFound()) ; } @Test @TestDescription("์ด๋ฒคํธ๋ฅผ ์ ์์ ์ผ๋ก ์์ ํ๊ธฐ") public void updateEvent() throws Exception { // Given Account account = createAccount(); Event event = this.generatedEvent(200, account); EventDto eventDto = modelMapper.map(event, EventDto.class); String eventName = "Update event"; eventDto.setName(eventName); // When this.mockMvc.perform(put("/api/events/{id}",event.getId()) .header(HttpHeaders.AUTHORIZATION, getBearerToken(false)) .contentType(MediaType.APPLICATION_JSON_UTF8) .content(objectMapper.writeValueAsString(eventDto)) .accept(MediaTypes.HAL_JSON) ) .andDo(print()) .andExpect(status().isOk()) .andExpect(jsonPath("name").value(eventName)) .andExpect(jsonPath("_links.self").exists()) .andDo(document("update-event")) ; } @Test @TestDescription("์ ๋ ฅ๊ฐ์ด ๋น์ด์๋ ๊ฒฝ์ฐ ์ด๋ฒคํธ ์์ ์คํจ") public void updateEvent_400_Empty() throws Exception { //Given Event event = this.generatedEvent(200); EventDto eventDto = new EventDto(); this.mockMvc.perform(put("/api/events/{id}",event.getId()) .header(HttpHeaders.AUTHORIZATION, getBearerToken(true)) .contentType(MediaType.APPLICATION_JSON_UTF8) .content(objectMapper.writeValueAsString(eventDto)) .accept(MediaTypes.HAL_JSON) ) .andDo(print()) .andExpect(status().isBadRequest()) ; } @Test @TestDescription("์ ๋ ฅ๊ฐ์ด ์๋ชป๋ ๊ฒฝ์ฐ ์ด๋ฒคํธ ์์ ์คํจ") public void updateEvent_400_Wrong() throws Exception { //Given Event event = this.generatedEvent(200); EventDto eventDto = modelMapper.map(event, EventDto.class); eventDto.setBasePrice(20000); eventDto.setMaxPrice(10000); this.mockMvc.perform(put("/api/events/{id}",event.getId()) .header(HttpHeaders.AUTHORIZATION, getBearerToken(true)) .contentType(MediaType.APPLICATION_JSON_UTF8) .content(objectMapper.writeValueAsString(eventDto)) .accept(MediaTypes.HAL_JSON) ) .andDo(print()) .andExpect(status().isBadRequest()) ; } @Test @TestDescription("์กด์ฌํ์ง ์๋ ์ด๋ฒคํธ ์์ ") public void updateEvent_404() throws Exception { //Given Event event = this.generatedEvent(200); EventDto eventDto = modelMapper.map(event, EventDto.class); this.mockMvc.perform(put("/api/events/12341234") .header(HttpHeaders.AUTHORIZATION, getBearerToken(true)) .contentType(MediaType.APPLICATION_JSON_UTF8) .content(objectMapper.writeValueAsString(eventDto)) .accept(MediaTypes.HAL_JSON) ) .andDo(print()) .andExpect(status().isNotFound()) ; } private Event generatedEvent(int i, Account account) { Event event = BuildEvent(i); event.setManager(account); return this.eventRepository.save(event); } private Event generatedEvent(int i) { Event event = BuildEvent(i); return this.eventRepository.save(event); } private Event BuildEvent(int i) { Event event = Event.builder() .name("Srping") .description("Spring API Development with Spring") .beginEnrollmentDateTime(LocalDateTime.of(2020, 02, 19, 14, 19)) .closeEnrollmentDateTime(LocalDateTime.of(2020, 02, 20, 14, 19)) .beginEventDateTime(LocalDateTime.of(2020, 02, 21, 14, 19)) .endEventDateTime(LocalDateTime.of(2020, 02, 22, 14, 19)) .basePrice(100) .maxPrice(200) .limitOfEnrollment(100) .location("Daejeon") .free(false) .offline(true) .eventStatus(EventStatus.DRAFT) .build(); return event; } private String getBearerToken(boolean needToCreateAccount) throws Exception { return "Bearer " + getAcessToken(needToCreateAccount); } private Account createAccount() { Account khj = Account.builder() .email(appProperties.getAdminUsername()) .password(appProperties.getAdminPassword()) .roles(Set.of(AccountRole.ADMIN, AccountRole.USER)) .build(); return this.accountService.saveAccount(khj); } private String getAcessToken(boolean needToCreateAccount) throws Exception { if(needToCreateAccount) { createAccount(); } ResultActions perform = this.mockMvc.perform(post("/oauth/token") .with(httpBasic(appProperties.getClientId(), appProperties.getClientSecret())) .param("username", appProperties.getAdminUsername()) .param("password", appProperties.getAdminPassword()) .param("grant_type", "password") ) .andDo(print()) .andExpect(status().isOk()) .andExpect(jsonPath("access_token").exists()) ; var responseBody = perform.andReturn().getResponse().getContentAsString(); Jackson2JsonParser parser = new Jackson2JsonParser(); return parser.parseMap(responseBody).get("access_token").toString(); } }
- 0
- 5
- 455
Q&A
JunitParams ๊ด๋ จ ์ง๋ฌธ ๋๋ฆฝ๋๋ค.
์ ์ฅ๋ ๊ฐ์ฌํฉ๋๋ค. ํด๊ฒฐํ์ต๋๋ค. ์์ผ๋ก๋ ํญ์ ์ข์ ๊ฐ์ ๋ถํ๋๋ฆฝ๋๋ค!
- 3
- 3
- 6.5K




