test(order-service): kafka 전송 테스트 코드, order 테스트 코드 작성

- kafka 전송 테스트 코드
- order 테스트 코드 작성
This commit is contained in:
hoon7566
2022-03-10 14:14:28 +09:00
parent 5d737a1127
commit 58990c759c
6 changed files with 223 additions and 71 deletions

View File

@@ -83,7 +83,11 @@ operation::prevOrder-get-BindException[snippets='curl-request,http-request,http-
=== 주문 내역 페이지
operation::api-customer-order-history[snippets='curl-request,http-request,http-response,request-headers,request-parameters,response-fields']
=== 장바구니 상품 추가
operation::add-item-to-basket[snippets='curl-request,http-request,http-response,request-headers,request-body,request-fields']
=== 장바구니 내역 가져오기
operation::fetch-order[snippets='curl-request,http-request,http-response,request-headers,response-fields']
=== 주문하기
operation::save-order[snippets='curl-request,http-request,http-response,request-headers']

View File

@@ -1,38 +1,27 @@
package com.justpickup.orderservice.domain.order.dto;
import com.justpickup.orderservice.domain.order.entity.Order;
import com.justpickup.orderservice.domain.order.entity.OrderStatus;
import com.justpickup.orderservice.domain.orderItem.dto.OrderItemDto;
import com.justpickup.orderservice.domain.orderItem.entity.OrderItem;
import com.justpickup.orderservice.domain.orderItemOption.dto.OrderItemOptionDto;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;
@Getter
@NoArgsConstructor
@AllArgsConstructor
public class FetchOrderDto {
private Long id;
private Long userId;
private String userName;
private Long userCouponId;
private Long orderPrice;
private Long storeId;
private LocalDateTime orderTime;
private Long usedPoint;
private OrderStatus orderStatus;
private List<OrderItemDto> orderItemDtoList;

View File

@@ -0,0 +1,69 @@
package com.justpickup.orderservice.domain.order.service;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.justpickup.orderservice.domain.order.entity.Order;
import com.justpickup.orderservice.domain.order.entity.OrderStatus;
import com.justpickup.orderservice.domain.orderItem.dto.OrderItemDto;
import lombok.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
import java.util.List;
@Service
@Slf4j
@RequiredArgsConstructor
public class OrderSender {
private final KafkaTemplate<String, String> kafkaTemplate;
public void orderPlaced( KafkaSendOrderDto kafkaSendOrderDto) throws Exception{
ObjectMapper mapper = new ObjectMapper().registerModule(new JavaTimeModule());
String jsonInString = mapper.writeValueAsString(kafkaSendOrderDto);
kafkaTemplate.send("orderPlaced", jsonInString);
log.info("kafka Producer sent data from the Order microservice: "+ kafkaSendOrderDto);
}
@NoArgsConstructor
@Data
@AllArgsConstructor
@Builder
static class KafkaSendOrderDto{
private Long id;
private Long userId;
private String userName;
private Long userCouponId;
private Long orderPrice;
private Long storeId;
private LocalDateTime orderTime;
private Long usedPoint;
private OrderStatus orderStatus;
private List<OrderItemDto> orderItemDtoList;
// == 생성 메소드 == //
public static KafkaSendOrderDto createPrimitiveField(Order order) {
return KafkaSendOrderDto.builder()
.id(order.getId())
.userId(order.getUserId())
.userCouponId(order.getUserCouponId())
.orderPrice(order.getOrderPrice())
.orderTime(order.getOrderTime())
.storeId(order.getStoreId())
.usedPoint(order.getUsedPoint())
.orderStatus(order.getOrderStatus())
.build();
}
}
}

View File

@@ -1,10 +1,5 @@
package com.justpickup.orderservice.domain.order.service;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.justpickup.orderservice.domain.order.dto.FetchOrderDto;
import com.justpickup.orderservice.domain.order.dto.OrderDto;
import com.justpickup.orderservice.domain.order.dto.OrderSearchCondition;
@@ -29,11 +24,9 @@ import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.SliceImpl;
import org.springframework.data.support.PageableExecutionUtils;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
@@ -50,7 +43,9 @@ public class OrderServiceImpl implements OrderService {
private final OrderRepositoryCustom orderRepositoryCustom;
private final StoreClient storeClient;
private final UserClient userClient;
private final KafkaTemplate<String, String> kafkaTemplate;
private final OrderSender orderSender;
@Override
public List<OrderDto> findOrderMain(OrderSearchCondition condition, Long storeId) {
@@ -154,59 +149,13 @@ public class OrderServiceImpl implements OrderService {
.orElseThrow(() -> new OrderException("장바구니 정보를 찾을 수 없습니다."))
.setOrderStatus(OrderStatus.PLACED);
try{
send("orderPlaced",KafkaSendOrderDto.createPrimitiveField(order));
orderSender.orderPlaced(OrderSender.KafkaSendOrderDto.createPrimitiveField(order));
}catch (Exception ex){
throw new OrderException(ex.getMessage());
}
}
public void send(String topic, KafkaSendOrderDto kafkaSendOrderDto) throws Exception{
ObjectMapper mapper = new ObjectMapper().registerModule(new JavaTimeModule());
String jsonInString = mapper.writeValueAsString(kafkaSendOrderDto);
kafkaTemplate.send(topic, jsonInString);
log.info("kafka Producer sent data from the Order microservice: "+ kafkaSendOrderDto);
}
@NoArgsConstructor
@Data
@AllArgsConstructor
@Builder
static class KafkaSendOrderDto{
private Long id;
private Long userId;
private String userName;
private Long userCouponId;
private Long orderPrice;
private Long storeId;
// @JsonDeserialize(using = LocalDateTimeDeserializer.class)
private LocalDateTime orderTime;
private Long usedPoint;
private OrderStatus orderStatus;
private List<OrderItemDto> orderItemDtoList;
// == 생성 메소드 == //
public static KafkaSendOrderDto createPrimitiveField(Order order) {
return KafkaSendOrderDto.builder()
.id(order.getId())
.userId(order.getUserId())
.userCouponId(order.getUserCouponId())
.orderPrice(order.getOrderPrice())
.orderTime(order.getOrderTime())
.storeId(order.getStoreId())
.usedPoint(order.getUsedPoint())
.orderStatus(order.getOrderStatus())
.build();
}
}
}

View File

@@ -0,0 +1,105 @@
package com.justpickup.orderservice.domain.order.service;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.justpickup.orderservice.domain.order.entity.OrderStatus;
import com.justpickup.orderservice.domain.orderItem.dto.OrderItemDto;
import com.justpickup.orderservice.domain.orderItemOption.dto.OrderItemOptionDto;
import org.apache.kafka.clients.consumer.Consumer;
import org.apache.kafka.clients.consumer.ConsumerConfig;
import org.apache.kafka.clients.consumer.ConsumerRecord;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInstance;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.kafka.annotation.EnableKafka;
import org.springframework.kafka.core.DefaultKafkaConsumerFactory;
import org.springframework.kafka.core.DefaultKafkaProducerFactory;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.kafka.support.SendResult;
import org.springframework.kafka.test.EmbeddedKafkaBroker;
import org.springframework.kafka.test.context.EmbeddedKafka;
import org.springframework.kafka.test.utils.KafkaTestUtils;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.util.concurrent.ListenableFuture;
import java.time.LocalDateTime;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import static org.assertj.core.api.Assertions.assertThat;
@ExtendWith(SpringExtension.class)
@EnableKafka
@DirtiesContext
@EmbeddedKafka(topics = {"orderPlaced"})
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class OrderSenderTest {
private final String TEST_TOPIC = "orderPlaced";
private Consumer<Integer, String> consumer;
private KafkaTemplate<String, String> producer;
@Autowired
private EmbeddedKafkaBroker embeddedKafkaBroker;
@BeforeEach
void setup() {
System.out.println("beforeAll");
producer = configureProducer();
consumer = configureConsumer();
}
private Consumer<Integer, String> configureConsumer() {
Map<String, Object> consumerProps = KafkaTestUtils.consumerProps("testGroup", "true", embeddedKafkaBroker);
consumerProps.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "earliest");
Consumer<Integer, String> consumer = new DefaultKafkaConsumerFactory<Integer, String>(consumerProps)
.createConsumer();
consumer.subscribe(Collections.singleton(TEST_TOPIC));
return consumer;
}
private KafkaTemplate<String, String> configureProducer() {
Map<String, Object> producerProps = new HashMap<>(KafkaTestUtils.producerProps(embeddedKafkaBroker));
return new KafkaTemplate <>( new DefaultKafkaProducerFactory<>(producerProps));
}
@Test
void sendOrderPlaced() throws Exception{
//given
ObjectMapper mapper = new ObjectMapper().registerModule(new JavaTimeModule());
OrderSender.KafkaSendOrderDto kafkaSendOrderDto = new OrderSender.KafkaSendOrderDto(
1L,2L,"주문아이디",1L,12000L,2L, LocalDateTime.now(),3000L, OrderStatus.PLACED,
List.of(
OrderItemDto.of(1L,300L,3000L,2L,
List.of(new OrderItemOptionDto(2L)
,new OrderItemOptionDto(3L))
)
)
);
String jsonInString = mapper.writeValueAsString(kafkaSendOrderDto);
//when
ListenableFuture<SendResult<String, String>> orderPlaced = producer.send("orderPlaced", jsonInString);
System.out.println(orderPlaced.get().toString());
//then
ConsumerRecord<Integer, String> singleRecord = KafkaTestUtils.getSingleRecord(consumer, TEST_TOPIC);
assertThat(singleRecord).isNotNull();
assertThat(singleRecord.value()).isEqualTo(jsonInString);
}
}

View File

@@ -176,10 +176,39 @@ class OrderCustomerApiControllerTest {
@DisplayName("장바구니 정보 조회_성공")
void fetchOrder() throws Exception{
//Given
FetchOrderDto fetchOrderDto =
new FetchOrderDto(2L,2L,12000L,2L
,List.of(
OrderItemDto.of(1L,300L,3000L,2L,
List.of(new OrderItemOptionDto(2L)
,new OrderItemOptionDto(3L))
)
)
);
given(orderService.fetchOrder(2L)).willReturn(fetchOrderDto);
//When
ResultActions actions = mockMvc.perform(get(url + "/orders")
.header("user-id", "2")
);
//Then
actions.andExpect(status().isOk())
.andDo(print())
.andDo(document("fetch-order",
requestHeaders(headerWithName("user-id").description("유저 고유번호")),
responseFields(
fieldWithPath("code").description("결과 코드 SUCCESS/ERROR"),
fieldWithPath("message").description("메시지"),
fieldWithPath("data.storeId").description("매장 고유번호"),
fieldWithPath("data.totalPrice").description("총 합계"),
fieldWithPath("data._orderItemDtos[*].itemId").description("상품 고유번호"),
fieldWithPath("data._orderItemDtos[*].price").description("상품 가격"),
fieldWithPath("data._orderItemDtos[*].count").description("상품 갯수"),
fieldWithPath("data._orderItemDtos[*].itemOptionIds[*]").description("아이템 옵션들")
)));
}
@@ -189,8 +218,15 @@ class OrderCustomerApiControllerTest {
//Given
//When
ResultActions actions = mockMvc.perform(post(url + "/orders")
.header("user-id", "2")
);
//Then
actions.andExpect(status().isCreated())
.andDo(print())
.andDo(document("save-order",
requestHeaders(headerWithName("user-id").description("유저 고유번호"))
));
}