Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ControllerTest RestDocsSupport를 상속받아 테스트를 수행하도록 리팩토링 #132

Open
wants to merge 6 commits into
base: develop
Choose a base branch
from
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@ public static AcademyCalendarCreateParam to(AcademyCalendarCreateRequest request
.stream()
.map(lesson -> LessonScheduleCreateRequest.to(lesson))
.toList(),
LocalDate.parse(request.attendanceDate().getStartDateOfAttendance()),
LocalDate.parse(request.attendanceDate().getEndDateOfAttendance()),
LocalDate.parse(request.attendanceDate().startDateOfAttendance()),
LocalDate.parse(request.attendanceDate().endDateOfAttendance()),
request.isAlarmed,
request.childId,
request.dashboardId,
Expand All @@ -67,8 +67,8 @@ public record LessonScheduleCreateRequest(
public static LessonScheduleParam to(LessonScheduleCreateRequest request) {
return new LessonScheduleParam(
DayOfWeek.valueOf(request.dayOfWeek()),
LocalTime.parse(request.lessonTime().getLessonStartTime()),
LocalTime.parse(request.lessonTime().getLessonEndTime())
LocalTime.parse(request.lessonTime().lessonStartTime()),
LocalTime.parse(request.lessonTime().lessonEndTime())
);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,8 @@ public static AcademyCalendarUpdateParam to(AcademyCalendarUpdateRequest request
.stream()
.map(lesson -> LessonScheduleUpdateRequest.to(lesson))
.toList(),
LocalDate.parse(request.attendanceDate().getStartDateOfAttendance()),
LocalDate.parse(request.attendanceDate().getEndDateOfAttendance()),
LocalDate.parse(request.attendanceDate().startDateOfAttendance()),
LocalDate.parse(request.attendanceDate().endDateOfAttendance()),
request.isAlarmed,
memberId,
request.childId,
Expand All @@ -72,8 +72,8 @@ public record LessonScheduleUpdateRequest(
public static LessonScheduleParam to(LessonScheduleUpdateRequest request) {
return new LessonScheduleParam(
DayOfWeek.valueOf(request.dayOfWeek()),
LocalTime.parse(request.lessonTime().getLessonStartTime()),
LocalTime.parse(request.lessonTime().getLessonEndTime())
LocalTime.parse(request.lessonTime().lessonStartTime()),
LocalTime.parse(request.lessonTime().lessonEndTime())
);
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,20 +1,12 @@
package org.guzzing.studayserver.domain.calendar.controller.dto.request;

import com.fasterxml.jackson.annotation.JsonProperty;
import jakarta.validation.constraints.NotBlank;
import lombok.Getter;
import org.guzzing.studayserver.domain.calendar.controller.dto.request.validation.ValidAttendanceDate;

@Getter
@ValidAttendanceDate
public class AttendanceDate {

private String startDateOfAttendance;

private String endDateOfAttendance;

@NotBlank
public AttendanceDate(String startDateOfAttendance, String endDateOfAttendance) {
this.startDateOfAttendance = startDateOfAttendance;
this.endDateOfAttendance = endDateOfAttendance;
}
public record AttendanceDate(
String startDateOfAttendance,
String endDateOfAttendance) {
}
Original file line number Diff line number Diff line change
@@ -1,20 +1,12 @@
package org.guzzing.studayserver.domain.calendar.controller.dto.request;

import com.fasterxml.jackson.annotation.JsonProperty;
import jakarta.validation.constraints.NotBlank;
import lombok.Getter;
import org.guzzing.studayserver.domain.calendar.controller.dto.request.validation.ValidLessonTime;

@Getter
@ValidLessonTime
public class LessonTime {

private String lessonStartTime;

private String lessonEndTime;

@NotBlank
public LessonTime(String lessonStartTime, String lessonEndTime) {
this.lessonStartTime = lessonStartTime;
this.lessonEndTime = lessonEndTime;
}
public record LessonTime(
String lessonStartTime,
String lessonEndTime) {
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ public boolean isValid(AttendanceDate attendanceDate, ConstraintValidatorContext
}

try {
LocalDate startDate = LocalDate.parse(attendanceDate.getStartDateOfAttendance());
LocalDate endDate = LocalDate.parse(attendanceDate.getEndDateOfAttendance());
LocalDate startDate = LocalDate.parse(attendanceDate.startDateOfAttendance());
LocalDate endDate = LocalDate.parse(attendanceDate.endDateOfAttendance());

if (endDate.isAfter(startDate.plusYears(MAX_DIFFERENCE_YEAR)) || endDate.isBefore(startDate)) {
return false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ public boolean isValid(LessonTime lessonTime, ConstraintValidatorContext context
}

try {
LocalTime startTime = LocalTime.parse(lessonTime.getLessonStartTime(), TIME_FORMATTER);
LocalTime endTime = LocalTime.parse(lessonTime.getLessonEndTime(), TIME_FORMATTER);
LocalTime startTime = LocalTime.parse(lessonTime.lessonStartTime(), TIME_FORMATTER);
LocalTime endTime = LocalTime.parse(lessonTime.lessonEndTime(), TIME_FORMATTER);

if (!isValidTimeRange(startTime, endTime, context) || !isStartTimeBeforeEndTime(startTime, endTime,
context)) {
Expand Down
38 changes: 38 additions & 0 deletions src/test/java/org/guzzing/studayserver/docs/RestDocsSupport.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package org.guzzing.studayserver.docs;

import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.documentationConfiguration;

import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.restdocs.RestDocumentationContextProvider;
import org.springframework.restdocs.RestDocumentationExtension;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;

@ExtendWith(RestDocumentationExtension.class)
public abstract class RestDocsSupport {

Comment on lines +16 to +18
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

설정 클래스가 아닌 추상 클래스를 선택하신 이유가 궁금합니다!!

protected MockMvc mockMvc;
protected ObjectMapper objectMapper;

@BeforeEach
void setup(RestDocumentationContextProvider provider) {
JavaTimeModule javaTimeModule = new JavaTimeModule();
javaTimeModule.addSerializer(LocalDateTimeSerializer.INSTANCE);

objectMapper = new ObjectMapper()
.setSerializationInclusion(Include.NON_NULL)
.registerModule(javaTimeModule);

mockMvc = MockMvcBuilders.standaloneSetup(initController())
.setMessageConverters()
.apply(documentationConfiguration(provider))
.build();
}

protected abstract Object initController();
}
Original file line number Diff line number Diff line change
@@ -1,74 +1,62 @@
package org.guzzing.studayserver.domain.calendar.controller;

import static org.mockito.Mockito.mock;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.put;
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

import com.fasterxml.jackson.databind.ObjectMapper;
import java.time.DayOfWeek;
import java.util.List;
import java.util.stream.Stream;
import org.guzzing.studayserver.docs.RestDocsSupport;
import org.guzzing.studayserver.domain.calendar.controller.dto.request.AcademyCalendarCreateRequest;
import org.guzzing.studayserver.domain.calendar.controller.dto.request.AcademyCalendarUpdateRequest;
import org.guzzing.studayserver.domain.calendar.controller.dto.request.AttendanceDate;
import org.guzzing.studayserver.domain.calendar.controller.dto.request.LessonTime;
import org.guzzing.studayserver.domain.calendar.facade.AcademyCalendarFacade;
import org.guzzing.studayserver.domain.calendar.model.Periodicity;
import org.guzzing.studayserver.domain.calendar.service.AcademyCalendarService;
import org.guzzing.studayserver.testutil.WithMockCustomOAuth2LoginUser;
import org.guzzing.studayserver.testutil.fixture.academycalender.AcademyCalenderFixture;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MockMvc;

@WebMvcTest(AcademyCalendarController.class)
class AcademyCalendarControllerTest {
class AcademyCalendarControllerTest extends RestDocsSupport {

@Autowired
private MockMvc mvc;

@Autowired
private ObjectMapper objectMapper;

@MockBean
private AcademyCalendarService academyCalendarService;

@MockBean
private AcademyCalendarFacade academyCalendarFacade;

@Override
protected Object initController() {
academyCalendarService = mock(AcademyCalendarService.class);
academyCalendarFacade = mock(AcademyCalendarFacade.class);
Comment on lines +33 to +34
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

저희 Mock 제거하기로 해서, 이 코드는 없어질 것 같네요!

return new AcademyCalendarController(academyCalendarService, academyCalendarFacade);
}

@DisplayName(" 예외가 발생하는 상황을 검증한다.")
@Nested
class ThrowException {

@DisplayName("스케줄 생성할 때 요청값에 대해 검증한다.")
@WithMockCustomOAuth2LoginUser
@ParameterizedTest
@MethodSource("provideInvalidCreateRequests")
void createAcademyCalendar(AcademyCalendarCreateRequest academyCalendarCreateRequest) throws Exception {
//Then
mvc.perform(post("/academy-schedules")
mockMvc.perform(post("/academy-schedules")
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(academyCalendarCreateRequest))
.with(csrf()))
.content(objectMapper.writeValueAsString(academyCalendarCreateRequest)))
.andExpect(status().isBadRequest());
}

@DisplayName("스케줄 수정할 때 요청값에 대해 검증한다.")
@WithMockCustomOAuth2LoginUser
@ParameterizedTest
@MethodSource("provideInvalidUpdateRequests")
void updateSchedule(AcademyCalendarUpdateRequest academyCalendarUpdateRequest) throws Exception {
mvc.perform(put("/academy-schedules")
mockMvc.perform(put("/academy-schedules")
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(academyCalendarUpdateRequest))
.with(csrf()))
.content(objectMapper.writeValueAsString(academyCalendarUpdateRequest)))
.andExpect(status().isBadRequest());
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
import static org.springframework.restdocs.operation.preprocess.Preprocessors.preprocessRequest;
Expand All @@ -24,11 +25,11 @@
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

import com.epages.restdocs.apispec.ResourceSnippetParameters;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.time.LocalDate;
import java.time.LocalTime;
import java.util.List;
import java.util.stream.Stream;
import org.guzzing.studayserver.docs.RestDocsSupport;
import org.guzzing.studayserver.domain.child.controller.request.ChildCreateRequest;
import org.guzzing.studayserver.domain.child.controller.request.ChildModifyRequest;
import org.guzzing.studayserver.domain.child.controller.response.ChildrenFindResponse;
Expand All @@ -37,51 +38,38 @@
import org.guzzing.studayserver.domain.child.service.ChildWithScheduleResult;
import org.guzzing.studayserver.domain.child.service.param.ChildCreateParam;
import org.guzzing.studayserver.domain.child.service.result.ChildProfileImagePatchResult;
import org.guzzing.studayserver.testutil.WithMockCustomOAuth2LoginUser;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.restdocs.AutoConfigureRestDocs;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.http.MediaType;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.ResultActions;
import org.springframework.web.multipart.MultipartFile;

@WebMvcTest(ChildRestController.class)
@AutoConfigureRestDocs
@AutoConfigureMockMvc(addFilters = false)
class ChildRestControllerTest {
class ChildRestControllerTest extends RestDocsSupport {

private static final String TAG = "아이 API";

@Autowired
private MockMvc mockMvc;

@MockBean
private ChildService childService;

@MockBean
private ChildFacade childFacade;

@Autowired
private ObjectMapper objectMapper;
@Override
protected Object initController() {
childService = mock(ChildService.class);
childFacade = mock(ChildFacade.class);
return new ChildRestController(childService, childFacade);
}

@Nested
class Create {

@DisplayName("아이 생성시 정상 값이면 OK를 반환한다.")
@Test
@WithMockCustomOAuth2LoginUser(memberId = 1L)
void statusIsOk() throws Exception {
// Given
ChildCreateRequest request = new ChildCreateRequest("childName1", "초등학교 1학년");
Expand All @@ -100,7 +88,6 @@ void statusIsOk() throws Exception {

@DisplayName("아이 생성시 잘못된 요청은 400에러를 반환한다.")
@ParameterizedTest
@WithMockCustomOAuth2LoginUser(memberId = 1L)
@MethodSource("provideInvalidRequests")
void statusIsBadRequest(ChildCreateRequest invalidRequest) throws Exception {
// Then
Expand All @@ -126,7 +113,6 @@ private static Stream<Arguments> provideInvalidRequests() {
}

@DisplayName("멤버에 할당된 아이들의 정보를 반환한다.")
@WithMockCustomOAuth2LoginUser(memberId = 1L)
@Test
void findChildren_success() throws Exception {
// Given
Expand All @@ -149,7 +135,6 @@ void findChildren_success() throws Exception {
}

@DisplayName("아이를 삭제한다.")
@WithMockCustomOAuth2LoginUser()
@Test
void delete_success() throws Exception {
// Given
Expand All @@ -164,7 +149,6 @@ void delete_success() throws Exception {
class modify {

@DisplayName("아이의 정보를 수정한다.")
@WithMockCustomOAuth2LoginUser(memberId = 1L)
@Test
void success() throws Exception {
// Given
Expand All @@ -183,7 +167,6 @@ void success() throws Exception {
}

@DisplayName("잘못된 요청이 들어오면 예외를 발생시킨다.")
@WithMockCustomOAuth2LoginUser()
@ParameterizedTest
@MethodSource("provideInvalidRequests")
void givenInvalidRequest_throwsException(ChildModifyRequest invalidRequest) throws Exception {
Expand Down
Loading