@WebMvcTest(PolicyController.class)
@MockBean(JpaMetamodelMappingContext.class)
class PolicyControllerTest {
@MockBean
private PolicyService policyService;
private int port = 8080;
@Autowired
private ObjectMapper objectMapper;
@Autowired
private MockMvc mockMvc;
private static AddRatePolicyForBookRequest addRatePolicyForBookRequest;
private static AddRatePolicyForCategoryRequest addRatePolicyForCategoryRequest;
private static AddRatePolicyForBookResponse addRatePolicyForBookResponse;
private static AddRatePolicyForCategoryResponse addRatePolicyForCategoryResponse;
@BeforeAll
static void setUp() throws NoSuchFieldException {
// 정률정책 for Book 추가 요청
addRatePolicyForBookRequest = new AddRatePolicyForBookRequest();
for(Field field : addRatePolicyForBookRequest.getClass().getDeclaredFields()){
field.setAccessible(true);
}
ReflectionUtils.setField(
addRatePolicyForBookRequest.getClass().getDeclaredField("discountRate")
,addRatePolicyForBookRequest
, 10);
ReflectionUtils.setField(
addRatePolicyForBookRequest.getClass().getDeclaredField("minimumOrderAmount")
,addRatePolicyForBookRequest
, 30000);
ReflectionUtils.setField(
addRatePolicyForBookRequest.getClass().getDeclaredField("maximumDiscountPrice")
,addRatePolicyForBookRequest
, 10000);
ReflectionUtils.setField(
addRatePolicyForBookRequest.getClass().getDeclaredField("expirationPeriodStart")
,addRatePolicyForBookRequest
, LocalDateTime.of(2024,1,1,12,0));
ReflectionUtils.setField(
addRatePolicyForBookRequest.getClass().getDeclaredField("expirationPeriodEnd")
,addRatePolicyForBookRequest
, LocalDateTime.of(2024,1,10,12,0));
ReflectionUtils.setField(
addRatePolicyForBookRequest.getClass().getDeclaredField("name")
,addRatePolicyForBookRequest
, "테스트용 정책");
ReflectionUtils.setField(
addRatePolicyForBookRequest.getClass().getDeclaredField("description")
,addRatePolicyForBookRequest
, "테스트용 정책 설명");
ReflectionUtils.setField(
addRatePolicyForBookRequest.getClass().getDeclaredField("bookId")
,addRatePolicyForBookRequest
,1L);
ReflectionUtils.setField(
addRatePolicyForBookRequest.getClass().getDeclaredField("policyStatusId")
,addRatePolicyForBookRequest
,0);
// 정률정책 for Book 추가 응답
addRatePolicyForBookResponse = new AddRatePolicyForBookResponse(
10,
30000,
10000,
LocalDateTime.of(2024,1,1,12,0),
LocalDateTime.of(2024,1,10,12,0),
"테스트용 정책",
"테스트용 정책 설명",
1L,
0
);
}
@Test
@DisplayName("정룰정책 for Book 요청시 - 200과 응답이 잘 돌아오는지 확인")
void addRatePolicyForBookTest() throws Exception {
Mockito.when(policyService.addRatePolicyForBook(Mockito.any(AddRatePolicyForBookRequest.class)))
.thenReturn(addRatePolicyForBookResponse);
String url = "http://localhost:"+port +"/task/policies/rate/book";
String req = objectMapper.writeValueAsString(addRatePolicyForBookRequest);
mockMvc.perform(post(url).header("X-MEMBER-ID",1L)
.contentType(MediaType.APPLICATION_JSON)
.content(req))
.andExpect(jsonPath("$.discountRate").value(10))
.andExpect(jsonPath("$.minimumOrderAmount").value(30000))
.andExpect(jsonPath("$.maximumDiscountPrice").value(10000))
.andExpect(jsonPath("$.expirationPeriodStart")
.value(LocalDateTime.of(2024,1,1,12,0,0)))
.andExpect(jsonPath("$.expirationPeriodEnd")
.value(LocalDateTime.of(2024,1,10,12,0,0)))
.andExpect(jsonPath("$.name").value("테스트용 정책"))
.andExpect(jsonPath("$.description").value("테스트용 정책 설명"))
.andExpect(jsonPath("$.bookId").value(1L))
.andExpect(jsonPath("$.policyStatusId").value(0));
}
다음과 같이 컨트롤러에 대한 테스트코드를 작성중이었다.
어떤 req를 보냈을때 , 어떤 resp를 기대하는지에 대한 코드였다
request를 보내게 된다면,
response는 request의 필드에 담겨있는 값들을 그대로 가지고 돌아오게 되어 있었다.
그래서
요청의 "expirationPeriodStart" 에
LocalDateTime.of(2024,1,1,12,0) 을
ReflectionUtils.setField(
addRatePolicyForBookRequest.getClass().getDeclaredField("expirationPeriodStart")
,addRatePolicyForBookRequest
, LocalDateTime.of(2024,1,1,12,0));
응답의 기댓값 역시
LocalDateTime.of(2024,1,1,12,0)으로 설정해주었다
.andExpect(jsonPath("$.expirationPeriodStart")
.value(LocalDateTime.of(2024,1,1,12,0,0)))
그리고 테스트 코드를 실행하니 문제가 발생하였다.
java.lang.AssertionError: JSON path "$.expirationPeriodStart" expected:<2024-01-01T12:00> but was:<2024-01-01T12:00:00>
Expected :2024-01-01T12:00
Actual :2024-01-01T12:00:00
LocalDateTime.of(2024,1,1,12,0)을 넣어서
기대값으로 설정된 값은 2024-01-01T12:00 이었는데
LocalDateTime.of(2024,1,1,12,0)을 넣어서
request로 날아온 실제 값은 2024-01-01T12:00:00 이었다.
원인은
LocalDateTime이 직렬화 될때와
LocalDateTime이 jsonPath의 value() 메서드를 통과할때
변환되는 형태가 다르기 때문이었다.
LocalDateTime이 직렬화 될 때에는
jackson이 LocalDateTime을 직렬화할 때 항상 전체 포맷(초 단위 포함)을 사용한다
반면에
LocalDateTime이 jsonPat의 value 메서드를 통과할때에는
ISO_LOCAL_DATE_TIME 포맷의 축약 버전으로 변환된다고 한다
(초 단위가 0일 경우 생략).
그래서 형태가 다르고 일치하지 않는것이었다
기댓값의 응답 형태를 직접 입력해주는것으로 바꿔주었다
.andExpect(jsonPath("$.expirationPeriodStart")
.value("2024-01-01T12:00:00"))