nhnacademy-be3-baegopa / baegopa_delivery

0 stars 0 forks source link

배송접수 REST-API #4

Open lightbell03 opened 1 year ago

yoho94 commented 11 months ago

전체적인 배송 시스템은 더미 시스템 이다.

실제로 기사를 매칭하지 않고 실제로 배달을 가는 것이 아니라 일정 랜덤한 시간을 갖고 배송 절차가 이루어진다.

지금은 더미 시스템이지만 추후 실제로 기사 매칭이나 배송진행 시스템이 들어 올 것을 대비하여 서비스 구조를 아래처럼 가져갔다.

만약 실제 기사매칭, 배송진행 서비스가 들어간다면 여기서 DummyDeliveryService 가 빠지고 기사를위한 Controller, Service들을 만들어 DeliveryCallbackService를 활용하면 된다.

yoho94 commented 11 months ago

아직 스토어 쪽에 배송 호출이나 콜백 받는 기능이 없어 통합테스트를 작성해보았다. 테스트를 작성하면서 겪었던 애로사항들을 정리.

  1. 통합 테스트 시 port 문제.
    
    @RestController
    @RequestMapping("/test/callback")
    @Slf4j
    public class CallbackTestController {
    @PostMapping
    public CallbackResponse returnCallbackResponse(@RequestBody CallbackResponse callbackResponse) {
        log.info("callbackResponse : {}", callbackResponse.toString());
        return callbackResponse;
    }

}

먼저 위와 같은 클래스를 테스트쪽에 작성하여 해당 콜백이 되는지 확인해보고 싶었다.

``` java
// ... 생략
DeliveryRequestRequest deliveryRequestRequest = new DeliveryRequestRequest();
ReflectionTestUtils.setField(deliveryRequestRequest, "deliveryAddress", "배달 주소");
ReflectionTestUtils.setField(deliveryRequestRequest, "price", 5000);
ReflectionTestUtils.setField(deliveryRequestRequest, "reqStore", "가게1");
ReflectionTestUtils.setField(deliveryRequestRequest, "reqStoreAddress", "가게 주소");
ReflectionTestUtils.setField(deliveryRequestRequest, "prepDatetime", LocalDateTime.now());
ReflectionTestUtils.setField(deliveryRequestRequest, "reqMemo", "메모");
ReflectionTestUtils.setField(deliveryRequestRequest, "callbackId", "123");
ReflectionTestUtils.setField(deliveryRequestRequest, "callbackUrl", "http://local.baegopa.store:8086/test/callback");
mockMvc.perform(post("/delivery")
                .contentType(MediaType.APPLICATION_JSON)
                .content(objectMapper.writeValueAsString(deliveryRequestRequest)))
        .andDo(print())
        .andExpect(status().isOk());

// ... 생략

여기서 local.baegopa.store는 127.0.0.1 을 hosts에 등록 한 것이다.

위 테스트 코드를 실행하면 CallbackTestController에서 log가 찍혀야하는데 계속 오류가 나왔다.

해당 오류는 RestTemplate 가 http://local.baegopa.store:8086/test/callback 를 찾지 못해서 발생.

yoho94 commented 11 months ago
  1. 그래서 콜백을 어떻게 테스트 하는가?

처음에는 Thread.sleep() 기능을 이용하여 무작정 대기시키고 DB에 데이터가 정상적으로 진행 됐는지 확인을 진행하였다. 그랬더니 소나큐브에서 경고를 주었다. 소나큐브가 제시한 방법은 await() 를 사용하라 였다.

아래 라이브러리를 사용하면 편하게 비동기, 멀티쓰레드 테스트를 진행 할 수 있다.

        <dependency>
            <groupId>org.awaitility</groupId>
            <artifactId>awaitility</artifactId>
            <version>4.2.0</version>
            <scope>test</scope>
        </dependency>
        await()
                .atMost(Duration.ofMinutes(1)) // 최대 1분까지
                .pollInterval(Duration.ofSeconds(5)) // 5초 간격으로 검사
                .until(() -> { // true 가 뜰 때까지 검사
                    DeliveryInfoEntity deliveryInfoEntity = deliveryInfoRepository.findAll().get(0);

                    DeliveryStateCode stateCode = deliveryStateHistoryRepository.findAll(Example.of(DeliveryStateHistoryEntity.builder()
                                    .deliveryInfoEntity(deliveryInfoEntity)
                                    .build()), Sort.by(Sort.Direction.DESC, "createDatetime"))
                            .get(0)
                            .getDeliveryStateCode();

                    log.info("stateCode : {}, {}", stateCode, stateCode.getName());

                    return DeliveryStateCode.A6.equals(stateCode) // 거절이거나
                            || DeliveryStateCode.A5.equals(stateCode) // 취소이거나
                            || DeliveryStateCode.A4.equals(stateCode); // 배송완료이면
                });