inflearn logo
강의

講義

知識共有

Practical Testing: 実用的なテストガイド

Spring REST Docs

OrderControllerDocsTest 작성 해봤는데요. 날짜 형식이 이상하게 나와요

183

ewgregerg c

投稿した質問数 26

0

@DisplayName("주문 생성 API")
  @Test
  void createOrder() throws Exception {
    OrderCreateRequest request = OrderCreateRequest.builder()
        .productNumbers(List.of("001"))
        .build();

    LocalDateTime now = LocalDateTime.now();

    given(orderService.createOrder(any(OrderCreateServiceRequest.class), any(LocalDateTime.class)))
        .willReturn(OrderResponse.builder()
            .id(1L)
            .totalPrice(4000)
            .registeredDateTime(now)
            .products(List.of(ProductResponse.builder()
                .id(1L)
                .productNumber("001")
                .type(ProductType.HANDMADE)
                .sellingStatus(ProductSellingStatus.SELLING)
                .name("아메리카노")
                .price(4000)
                .build()))
            .build());

    mockMvc.perform(post("/api/v1/orders/new")
            .contentType(MediaType.APPLICATION_JSON)
            .content(objectMapper.writeValueAsString(request)))
        .andDo(print())
        .andExpect(status().isOk())
        .andExpect(jsonPath("$.code").value("200"))
        .andExpect(jsonPath("$.message").value("OK"))
        .andExpect(jsonPath("$.status").value("OK"))
        .andDo(document("order-create",
            preprocessRequest(prettyPrint()),
            preprocessResponse(prettyPrint()),
            requestFields(
                fieldWithPath("productNumbers").type(JsonFieldType.ARRAY)
                    .description("상품 번호")
            ),
            responseFields(
                fieldWithPath("code").type(JsonFieldType.NUMBER)
                    .description("코드"),
                fieldWithPath("status").type(JsonFieldType.STRING)
                    .description("상태"),
                fieldWithPath("message").type(JsonFieldType.STRING)
                    .description("메시지"),
                fieldWithPath("data").type(JsonFieldType.OBJECT)
                    .description("응답 데이터"),
                fieldWithPath("data.id").type(JsonFieldType.NUMBER)
                    .description("주문 ID"),
                fieldWithPath("data.totalPrice").type(JsonFieldType.NUMBER)
                    .description("주문 총 금액"),
                fieldWithPath("data.registeredDateTime").type(JsonFieldType.ARRAY)
                    .description("주문 시각"),
                fieldWithPath("data.products").type(JsonFieldType.ARRAY)
                    .description("주문 상품"),
                fieldWithPath("data.products[].id").type(JsonFieldType.NUMBER)
                    .description("상품 ID"),
                fieldWithPath("data.products[].productNumber").type(JsonFieldType.STRING)
                    .description("상품 번호"),
                fieldWithPath("data.products[].type").type(JsonFieldType.STRING)
                    .description("상품 타입"),
                fieldWithPath("data.products[].sellingStatus").type(JsonFieldType.STRING)
                    .description("상품 상태"),
                fieldWithPath("data.products[].name").type(JsonFieldType.STRING)
                    .description("상품 이름"),
                fieldWithPath("data.products[].price").type(JsonFieldType.NUMBER)
                    .description("상품 가격")
            )));

  }

 

image.png

처음에 테스트 코드 작성시에

ieldWithPath("data.registeredDateTime").type(JsonFieldType.ARRAY) .description("주문 시각"),

이 부분을 JsontFieldType.STRING 으로 했더니 테스트 실패 메시지에 해당 타입이 Array 라고 해서 바꿨는데... 문서에 저렇게 나옵니다. 이게 맞는건지 궁금합니다.

spring tdd jpa mockito 소프트웨어-테스트 junit5

回答 2

1

communityai8509

안녕하세요, 인프런 AI 인턴입니다. ewgregerg c님!

LocalDateTime 의 직렬화 문제로 인해 registeredDateTime 이 JSON 배열로 표현되는 상황을 겪고 계신 것 같습니다. 이는 LocalDateTime 이 기본적으로 ObjectMapper configuration에 의해 배열으로 직렬화되기 때문입니다.

해결 방안

  1. 직렬화 설정 변경: JavaTimeModule 을 사용하고 WRITE_DATES_AS_TIMESTAMPS 옵션을 false로 설정하면 LocalDateTime 이 ISO 8601 문자열 포맷으로 직렬화됩니다.
   objectMapper.registerModule(new JavaTimeModule());
   objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
  1. 필드 설정 확인: 테스트에서 fieldWithPath("data.registeredDateTime").type(JsonFieldType.ARRAY) 로 설정하셨다면, 문자열 포맷으로 변경 후 JsonFieldType.STRING 으로 설정을 업데이트 해주시길 바랍니다.

  2. DTO 클래스의 어노테이션 사용: @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss") 을 사용하여 원하는 형식으로 직렬화할 수 있습니다.

추가 정보

위의 조치를 통해 문서화 형식과 실제 응답 형식을 일치시킬 수 있을 것입니다. 테스트 코드와 프로덕션 코드 간의 간극을 줄이며, 다양한 설정을 통해 요구사항에 맞는 표현을 찾아보시길 바랍니다.

저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해 드리고 있습니다.
현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏
추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.

0

wbluke

안녕하세요, ewgregerg c 님!

AI 인턴이 잘 설명해준 것처럼, LocalDateTime의 직렬화 문제인데요. 설명에 나와있는대로 ObjectMapper의 설정을 해주시면 해소가 될 것으로 보입니다.

감사합니다. 🙂

private 상수 테스트 관련 질문

0

82

1

void는 어떻게 테스트하나요..? void로 애초에 코딩하면 안되나요??

0

124

2

커버리지는 어떻게 활용하시는지 궁금합니다.

0

159

2

테스트 문서화 질문입니다

0

104

2

단위테스트 질문이 있습니다

0

95

2

컨트롤러는 모킹을 한 이유가 궁금합니다.

0

100

2

ERD 가장자리에 있는 도메인 테스트 질문

0

87

2

DTO 검증 필드에 대한 테스트 코드 작성은 어디까지?

0

132

2

OrderCreateRequest DTO에 대해서 궁금한점

0

101

2

고전파의 테스트 대역 사용 대상, 공유 의존성

0

154

2

계층 관련 질문이 있습니다.

0

137

3

'코틀린'에서는 빌더를 따로 쓰지 않는데, 이 때는 어떻게 test fixture를 만드시는지 궁금합니다

1

122

2

혹시 update 로직은 어떻게 테스트하나요? (@Setter?)

0

133

2

단위테스트와 통합테스트의 경계가 궁금합니다.

0

227

2

Service+Repository 통합테스트 관련 질문입니다.

0

149

2

test 용 .yml

0

89

2

throws Exception

0

78

2

카페키오스크 클래스 문의 ,,

0

87

2

Rest docs 문서용 테스트코드를 따로 작성해야 되나요?

0

172

2

테스트 코드에서 필요한 생성자

0

137

1

tearDown 순서

0

115

2

@Builder 생성자 private

0

135

2

@DisplayName gradle / intellJ

0

92

2

36:40 초 부근에 tearDown 없어도 통과하는 이유가 궁금해요

0

180

2