Commit 1452f6b231bff6fd1977085de6762c59ef01d52d

Authored by YunaiV
1 parent 636b14cc

mall + trade:增肌爱 TradeCouponPriceCalculator 的单元测试

yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/sku/dto/ProductSkuRespDTO.java
... ... @@ -52,10 +52,6 @@ public class ProductSkuRespDTO {
52 52 */
53 53 private Integer stock;
54 54 /**
55   - * 预警预存
56   - */
57   - private Integer warnStock;
58   - /**
59 55 * 商品重量,单位:kg 千克
60 56 */
61 57 private Double weight;
... ...
yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/price/dto/PriceCalculateReqDTO.java
... ... @@ -12,6 +12,7 @@ import java.util.List;
12 12 * @author 芋道源码
13 13 */
14 14 @Data
  15 +@Deprecated
15 16 public class PriceCalculateReqDTO {
16 17  
17 18 /**
... ...
yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/price/PriceServiceTest.java
... ... @@ -57,54 +57,6 @@ public class PriceServiceTest extends BaseMockitoUnitTest {
57 57 private ProductSkuApi productSkuApi;
58 58  
59 59 @Test
60   - public void testCalculatePrice_memberDiscount() {
61   - // 准备参数
62   - // TODO 芋艿:userId = 1,实现 9 折;后续改成 mock
63   - PriceCalculateReqDTO calculateReqDTO = new PriceCalculateReqDTO().setUserId(1L)
64   - .setItems(singletonList(new PriceCalculateReqDTO.Item().setSkuId(10L).setCount(2)));
65   - // mock 方法(商品 SKU 信息)
66   - ProductSkuRespDTO productSku = randomPojo(ProductSkuRespDTO.class, o -> o.setId(10L).setPrice(100));
67   - when(productSkuApi.getSkuList(eq(asSet(10L)))).thenReturn(singletonList(productSku));
68   -
69   - // 调用
70   - PriceCalculateRespDTO priceCalculate = priceService.calculatePrice(calculateReqDTO);
71   - // 断言 Order 部分
72   - PriceCalculateRespDTO.Order order = priceCalculate.getOrder();
73   - assertEquals(order.getTotalPrice(), 200);
74   - assertEquals(order.getDiscountPrice(), 0);
75   - assertEquals(order.getPointPrice(), 0);
76   - assertEquals(order.getDeliveryPrice(), 0);
77   - assertEquals(order.getPayPrice(), 180);
78   - assertNull(order.getCouponId());
79   - // 断言 OrderItem 部分
80   - assertEquals(order.getItems().size(), 1);
81   - PriceCalculateRespDTO.OrderItem orderItem = order.getItems().get(0);
82   - assertEquals(orderItem.getSkuId(), 10L);
83   - assertEquals(orderItem.getCount(), 2);
84   - assertEquals(orderItem.getOriginalPrice(), 200);
85   - assertEquals(orderItem.getOriginalUnitPrice(), 100);
86   - assertEquals(orderItem.getDiscountPrice(), 20);
87   - assertEquals(orderItem.getPayPrice(), 180);
88   - assertEquals(orderItem.getOrderPartPrice(), 0);
89   - assertEquals(orderItem.getOrderDividePrice(), 180);
90   - // 断言 Promotion 部分
91   - assertEquals(priceCalculate.getPromotions().size(), 1);
92   - PriceCalculateRespDTO.Promotion promotion = priceCalculate.getPromotions().get(0);
93   - assertNull(promotion.getId());
94   - assertEquals(promotion.getName(), "会员折扣");
95   - assertEquals(promotion.getType(), PromotionTypeEnum.MEMBER.getType());
96   - assertEquals(promotion.getTotalPrice(), 200);
97   - assertEquals(promotion.getDiscountPrice(), 20);
98   - assertTrue(promotion.getMatch());
99   - assertEquals(promotion.getDescription(), "会员折扣:省 0.20 元");
100   - PriceCalculateRespDTO.PromotionItem promotionItem = promotion.getItems().get(0);
101   - assertEquals(promotion.getItems().size(), 1);
102   - assertEquals(promotionItem.getSkuId(), 10L);
103   - assertEquals(promotionItem.getOriginalPrice(), 200);
104   - assertEquals(promotionItem.getDiscountPrice(), 20);
105   - }
106   -
107   - @Test
108 60 public void testCalculatePrice_discountActivity() {
109 61 // 准备参数
110 62 PriceCalculateReqDTO calculateReqDTO = new PriceCalculateReqDTO().setUserId(randomLongId())
... ... @@ -365,87 +317,6 @@ public class PriceServiceTest extends BaseMockitoUnitTest {
365 317 }
366 318  
367 319 @Test
368   - public void testCalculatePrice_coupon() {
369   - // 准备参数
370   - PriceCalculateReqDTO calculateReqDTO = new PriceCalculateReqDTO().setUserId(randomLongId())
371   - .setItems(asList(new PriceCalculateReqDTO.Item().setSkuId(10L).setCount(2),
372   - new PriceCalculateReqDTO.Item().setSkuId(20L).setCount(3),
373   - new PriceCalculateReqDTO.Item().setSkuId(30L).setCount(4)))
374   - .setCouponId(1024L);
375   - // mock 方法(商品 SKU 信息)
376   - ProductSkuRespDTO productSku01 = randomPojo(ProductSkuRespDTO.class, o -> o.setId(10L).setPrice(100).setSpuId(1L));
377   - ProductSkuRespDTO productSku02 = randomPojo(ProductSkuRespDTO.class, o -> o.setId(20L).setPrice(50).setSpuId(2L));
378   - ProductSkuRespDTO productSku03 = randomPojo(ProductSkuRespDTO.class, o -> o.setId(30L).setPrice(30).setSpuId(3L));
379   - when(productSkuApi.getSkuList(eq(asSet(10L, 20L, 30L)))).thenReturn(asList(productSku01, productSku02, productSku03));
380   - // mock 方法(优惠劵 Coupon 信息)
381   - CouponDO coupon = randomPojo(CouponDO.class, o -> o.setId(1024L).setName("程序员节")
382   - .setProductScope(PromotionProductScopeEnum.SPU.getScope()).setProductSpuIds(asList(1L, 2L))
383   - .setUsePrice(350).setDiscountType(PromotionDiscountTypeEnum.PERCENT.getType())
384   - .setDiscountPercent(50).setDiscountLimitPrice(70));
385   - when(couponService.validCoupon(eq(1024L), eq(calculateReqDTO.getUserId()))).thenReturn(coupon);
386   -
387   - // 调用
388   - PriceCalculateRespDTO priceCalculate = priceService.calculatePrice(calculateReqDTO);
389   - // 断言 Order 部分
390   - PriceCalculateRespDTO.Order order = priceCalculate.getOrder();
391   - assertEquals(order.getTotalPrice(), 470);
392   - assertEquals(order.getDiscountPrice(), 0);
393   - assertEquals(order.getPointPrice(), 0);
394   - assertEquals(order.getDeliveryPrice(), 0);
395   - assertEquals(order.getPayPrice(), 400);
396   - assertEquals(order.getCouponId(), 1024L);
397   - assertEquals(order.getCouponPrice(), 70);
398   - // 断言 OrderItem 部分
399   - assertEquals(order.getItems().size(), 3);
400   - PriceCalculateRespDTO.OrderItem orderItem01 = order.getItems().get(0);
401   - assertEquals(orderItem01.getSkuId(), 10L);
402   - assertEquals(orderItem01.getCount(), 2);
403   - assertEquals(orderItem01.getOriginalPrice(), 200);
404   - assertEquals(orderItem01.getOriginalUnitPrice(), 100);
405   - assertEquals(orderItem01.getDiscountPrice(), 0);
406   - assertEquals(orderItem01.getPayPrice(), 200);
407   - assertEquals(orderItem01.getOrderPartPrice(), 40);
408   - assertEquals(orderItem01.getOrderDividePrice(), 160);
409   - PriceCalculateRespDTO.OrderItem orderItem02 = order.getItems().get(1);
410   - assertEquals(orderItem02.getSkuId(), 20L);
411   - assertEquals(orderItem02.getCount(), 3);
412   - assertEquals(orderItem02.getOriginalPrice(), 150);
413   - assertEquals(orderItem02.getOriginalUnitPrice(), 50);
414   - assertEquals(orderItem02.getDiscountPrice(), 0);
415   - assertEquals(orderItem02.getPayPrice(), 150);
416   - assertEquals(orderItem02.getOrderPartPrice(), 30);
417   - assertEquals(orderItem02.getOrderDividePrice(), 120);
418   - PriceCalculateRespDTO.OrderItem orderItem03 = order.getItems().get(2);
419   - assertEquals(orderItem03.getSkuId(), 30L);
420   - assertEquals(orderItem03.getCount(), 4);
421   - assertEquals(orderItem03.getOriginalPrice(), 120);
422   - assertEquals(orderItem03.getOriginalUnitPrice(), 30);
423   - assertEquals(orderItem03.getDiscountPrice(), 0);
424   - assertEquals(orderItem03.getPayPrice(), 120);
425   - assertEquals(orderItem03.getOrderPartPrice(), 0);
426   - assertEquals(orderItem03.getOrderDividePrice(), 120);
427   - // 断言 Promotion 部分
428   - assertEquals(priceCalculate.getPromotions().size(), 1);
429   - PriceCalculateRespDTO.Promotion promotion01 = priceCalculate.getPromotions().get(0);
430   - assertEquals(promotion01.getId(), 1024L);
431   - assertEquals(promotion01.getName(), "程序员节");
432   - assertEquals(promotion01.getType(), PromotionTypeEnum.COUPON.getType());
433   - assertEquals(promotion01.getTotalPrice(), 350);
434   - assertEquals(promotion01.getDiscountPrice(), 70);
435   - assertTrue(promotion01.getMatch());
436   - assertEquals(promotion01.getDescription(), "优惠劵:省 0.70 元");
437   - assertEquals(promotion01.getItems().size(), 2);
438   - PriceCalculateRespDTO.PromotionItem promotionItem011 = promotion01.getItems().get(0);
439   - assertEquals(promotionItem011.getSkuId(), 10L);
440   - assertEquals(promotionItem011.getOriginalPrice(), 200);
441   - assertEquals(promotionItem011.getDiscountPrice(), 40);
442   - PriceCalculateRespDTO.PromotionItem promotionItem012 = promotion01.getItems().get(1);
443   - assertEquals(promotionItem012.getSkuId(), 20L);
444   - assertEquals(promotionItem012.getOriginalPrice(), 150);
445   - assertEquals(promotionItem012.getDiscountPrice(), 30);
446   - }
447   -
448   - @Test
449 320 public void testGetMeetCouponList() {
450 321 // 准备参数
451 322 PriceCalculateReqDTO calculateReqDTO = new PriceCalculateReqDTO().setUserId(1024L)
... ...
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeCouponPriceCalculator.java
... ... @@ -101,7 +101,8 @@ public class TradeCouponPriceCalculator implements TradePriceCalculator {
101 101 CouponRespDTO coupon) {
102 102 Predicate<TradePriceCalculateRespBO.OrderItem> matchPredicate = TradePriceCalculateRespBO.OrderItem::getSelected;
103 103 if (PromotionProductScopeEnum.SPU.getScope().equals(coupon.getProductScope())) {
104   - matchPredicate = orderItem -> coupon.getProductSpuIds().contains(orderItem.getSpuId());
  104 + matchPredicate = matchPredicate // 额外加如下条件
  105 + .and(orderItem -> coupon.getProductSpuIds().contains(orderItem.getSpuId()));
105 106 }
106 107 return filterList(result.getItems(), matchPredicate);
107 108 }
... ...
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradePriceCalculatorHelper.java
... ... @@ -15,8 +15,6 @@ import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.
15 15 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.getSumValue;
16 16 import static java.util.Collections.singletonList;
17 17  
18   -// TODO 芋艿:改成父类
19   -
20 18 /**
21 19 * {@link TradePriceCalculator} 的工具类
22 20 *
... ... @@ -107,6 +105,31 @@ public class TradePriceCalculatorHelper {
107 105 }
108 106  
109 107 /**
  108 + * 重新计算每个订单项的支付金额
  109 + *
  110 + * 【目前主要是单测使用】
  111 + *
  112 + * @param orderItems 订单项数组
  113 + */
  114 + public static void recountPayPrice(List<TradePriceCalculateRespBO.OrderItem> orderItems) {
  115 + orderItems.forEach(orderItem -> {
  116 + if (orderItem.getDiscountPrice() == null) {
  117 + orderItem.setDiscountPrice(0);
  118 + }
  119 + if (orderItem.getDeliveryPrice() == null) {
  120 + orderItem.setDeliveryPrice(0);
  121 + }
  122 + if (orderItem.getCouponPrice() == null) {
  123 + orderItem.setCouponPrice(0);
  124 + }
  125 + if (orderItem.getPointPrice() == null) {
  126 + orderItem.setPointPrice(0);
  127 + }
  128 + recountPayPrice(orderItem);
  129 + });
  130 + }
  131 +
  132 + /**
110 133 * 计算已选中的订单项,总支付金额
111 134 *
112 135 * @param orderItems 订单项数组
... ... @@ -114,7 +137,7 @@ public class TradePriceCalculatorHelper {
114 137 */
115 138 public static Integer calculateTotalPayPrice(List<TradePriceCalculateRespBO.OrderItem> orderItems) {
116 139 return getSumValue(orderItems,
117   - orderItem -> orderItem.getSelected() ? orderItem.getPayPrice() : 0, // 未选中的情况下,不计算支付金额
  140 + orderItem -> orderItem.getSelected() ? orderItem.getPayPrice() : 0, // 未选中的情况下,不计算支付金额
118 141 Integer::sum);
119 142 }
120 143  
... ...
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeRewardActivityPriceCalculator.java
... ... @@ -53,6 +53,9 @@ public class TradeRewardActivityPriceCalculator implements TradePriceCalculator
53 53 // 1.2 获得最大匹配的满减送活动的规则
54 54 RewardActivityMatchRespDTO.Rule rule = getMaxMatchRewardActivityRule(rewardActivity, orderItems);
55 55 if (rule == null) {
  56 + TradePriceCalculatorHelper.addNotMatchPromotion(result, orderItems,
  57 + rewardActivity.getId(), rewardActivity.getName(), PromotionTypeEnum.REWARD_ACTIVITY.getType(),
  58 + getRewardActivityNotMeetTip(rewardActivity));
56 59 return;
57 60 }
58 61  
... ...
yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderServiceTest.java
... ... @@ -8,6 +8,7 @@ import cn.iocoder.yudao.module.member.api.user.MemberUserApi;
8 8 import cn.iocoder.yudao.module.pay.api.order.PayOrderApi;
9 9 import cn.iocoder.yudao.module.pay.api.order.dto.PayOrderRespDTO;
10 10 import cn.iocoder.yudao.module.pay.enums.order.PayOrderStatusEnum;
  11 +import cn.iocoder.yudao.module.product.api.property.dto.ProductPropertyValueDetailRespDTO;
11 12 import cn.iocoder.yudao.module.product.api.sku.ProductSkuApi;
12 13 import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO;
13 14 import cn.iocoder.yudao.module.product.api.spu.ProductSpuApi;
... ... @@ -101,10 +102,10 @@ public class TradeOrderServiceTest extends BaseDbUnitTest {
101 102 // mock 方法(商品 SKU 检查)
102 103 ProductSkuRespDTO sku01 = randomPojo(ProductSkuRespDTO.class, o -> o.setId(1L).setSpuId(11L)
103 104 .setPrice(50).setStock(100)
104   - .setProperties(singletonList(new ProductSkuRespDTO.Property().setPropertyId(111L).setValueId(222L))));
  105 + .setProperties(singletonList(new ProductPropertyValueDetailRespDTO().setPropertyId(111L).setValueId(222L))));
105 106 ProductSkuRespDTO sku02 = randomPojo(ProductSkuRespDTO.class, o -> o.setId(2L).setSpuId(21L)
106 107 .setPrice(20).setStock(50))
107   - .setProperties(singletonList(new ProductSkuRespDTO.Property().setPropertyId(333L).setValueId(444L)));
  108 + .setProperties(singletonList(new ProductPropertyValueDetailRespDTO().setPropertyId(333L).setValueId(444L)));
108 109 when(productSkuApi.getSkuList(eq(asSet(1L, 2L)))).thenReturn(Arrays.asList(sku01, sku02));
109 110 // mock 方法(商品 SPU 检查)
110 111 ProductSpuRespDTO spu01 = randomPojo(ProductSpuRespDTO.class, o -> o.setId(11L)
... ... @@ -114,7 +115,7 @@ public class TradeOrderServiceTest extends BaseDbUnitTest {
114 115 when(productSpuApi.getSpuList(eq(asSet(11L, 21L)))).thenReturn(Arrays.asList(spu01, spu02));
115 116 // mock 方法(用户收件地址的校验)
116 117 AddressRespDTO addressRespDTO = new AddressRespDTO().setId(10L).setUserId(userId).setName("芋艿")
117   - .setMobile("15601691300").setAreaId(3306L).setPostCode("85757").setDetailAddress("土豆村");
  118 + .setMobile("15601691300").setAreaId(3306).setPostCode("85757").setDetailAddress("土豆村");
118 119 when(addressApi.getAddress(eq(10L), eq(userId))).thenReturn(addressRespDTO);
119 120 // mock 方法(价格计算)
120 121 PriceCalculateRespDTO.OrderItem priceOrderItem01 = new PriceCalculateRespDTO.OrderItem()
... ...
yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/price/TradePriceServiceImplTest.java 0 → 100644
  1 +package cn.iocoder.yudao.module.trade.service.price;
  2 +
  3 +import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest;
  4 +import cn.iocoder.yudao.module.product.api.property.dto.ProductPropertyValueDetailRespDTO;
  5 +import cn.iocoder.yudao.module.product.api.sku.ProductSkuApi;
  6 +import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO;
  7 +import cn.iocoder.yudao.module.product.api.spu.ProductSpuApi;
  8 +import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO;
  9 +import cn.iocoder.yudao.module.product.enums.spu.ProductSpuStatusEnum;
  10 +import cn.iocoder.yudao.module.trade.enums.order.TradeOrderTypeEnum;
  11 +import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateReqBO;
  12 +import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateRespBO;
  13 +import cn.iocoder.yudao.module.trade.service.price.calculator.TradePriceCalculator;
  14 +import org.junit.jupiter.api.Test;
  15 +import org.mockito.InjectMocks;
  16 +import org.mockito.Mock;
  17 +import org.mockito.Mockito;
  18 +
  19 +import java.util.Arrays;
  20 +import java.util.List;
  21 +
  22 +import static cn.iocoder.yudao.framework.common.util.collection.SetUtils.asSet;
  23 +import static java.util.Collections.singletonList;
  24 +import static org.junit.jupiter.api.Assertions.*;
  25 +import static org.mockito.Mockito.when;
  26 +
  27 +/**
  28 + * {@link TradePriceServiceImpl} 的单元测试
  29 + *
  30 + * @author 芋道源码
  31 + */
  32 +public class TradePriceServiceImplTest extends BaseMockitoUnitTest {
  33 +
  34 + @InjectMocks
  35 + private TradePriceServiceImpl tradePriceService;
  36 +
  37 + @Mock
  38 + private ProductSkuApi productSkuApi;
  39 + @Mock
  40 + private ProductSpuApi productSpuApi;
  41 + @Mock
  42 + private List<TradePriceCalculator> priceCalculators;
  43 +
  44 + @Test
  45 + public void testCalculatePrice() {
  46 + // 准备参数
  47 + TradePriceCalculateReqBO calculateReqBO = new TradePriceCalculateReqBO()
  48 + .setType(TradeOrderTypeEnum.NORMAL.getType()).setUserId(10L)
  49 + .setCouponId(20L).setAddressId(30L)
  50 + .setItems(Arrays.asList(
  51 + new TradePriceCalculateReqBO.Item().setSkuId(100L).setCount(1).setSelected(true),
  52 + new TradePriceCalculateReqBO.Item().setSkuId(200L).setCount(3).setSelected(true),
  53 + new TradePriceCalculateReqBO.Item().setSkuId(300L).setCount(6).setCartId(233L).setSelected(false)
  54 + ));
  55 + // mock 方法
  56 + List<ProductSkuRespDTO> skuList = Arrays.asList(
  57 + new ProductSkuRespDTO().setId(100L).setStock(500).setPrice(1000).setPicUrl("https://t.cn/1.png").setSpuId(1001L)
  58 + .setProperties(singletonList(new ProductPropertyValueDetailRespDTO().setPropertyId(1L).setPropertyName("颜色")
  59 + .setValueId(2L).setValueName("红色"))),
  60 + new ProductSkuRespDTO().setId(200L).setStock(400).setPrice(2000).setPicUrl("https://t.cn/2.png").setSpuId(1001L)
  61 + .setProperties(singletonList(new ProductPropertyValueDetailRespDTO().setPropertyId(1L).setPropertyName("颜色")
  62 + .setValueId(3L).setValueName("黄色"))),
  63 + new ProductSkuRespDTO().setId(300L).setStock(600).setPrice(3000).setPicUrl("https://t.cn/3.png").setSpuId(1001L)
  64 + .setProperties(singletonList(new ProductPropertyValueDetailRespDTO().setPropertyId(1L).setPropertyName("颜色")
  65 + .setValueId(4L).setValueName("黑色")))
  66 + );
  67 + when(productSkuApi.getSkuList(Mockito.eq(asSet(100L, 200L, 300L)))).thenReturn(skuList);
  68 + when(productSpuApi.getSpuList(Mockito.eq(asSet(1001L))))
  69 + .thenReturn(singletonList(new ProductSpuRespDTO().setId(1001L).setName("小菜").setCategoryId(666L)
  70 + .setStatus(ProductSpuStatusEnum.ENABLE.getStatus())));
  71 +
  72 + // 调用
  73 + TradePriceCalculateRespBO calculateRespBO = tradePriceService.calculatePrice(calculateReqBO);
  74 + // 断言
  75 + assertEquals(TradeOrderTypeEnum.NORMAL.getType(), calculateRespBO.getType());
  76 + assertEquals(0, calculateRespBO.getPromotions().size());
  77 + assertNull(calculateRespBO.getCouponId());
  78 + // 断言:订单价格
  79 + assertEquals(7000, calculateRespBO.getPrice().getTotalPrice());
  80 + assertEquals(0, calculateRespBO.getPrice().getDiscountPrice());
  81 + assertEquals(0, calculateRespBO.getPrice().getDeliveryPrice());
  82 + assertEquals(0, calculateRespBO.getPrice().getCouponPrice());
  83 + assertEquals(0, calculateRespBO.getPrice().getPointPrice());
  84 + assertEquals(7000, calculateRespBO.getPrice().getPayPrice());
  85 + // 断言:SKU 1
  86 + assertEquals(1001L, calculateRespBO.getItems().get(0).getSpuId());
  87 + assertEquals(100L, calculateRespBO.getItems().get(0).getSkuId());
  88 + assertEquals(1, calculateRespBO.getItems().get(0).getCount());
  89 + assertNull(calculateRespBO.getItems().get(0).getCartId());
  90 + assertTrue(calculateRespBO.getItems().get(0).getSelected());
  91 + assertEquals(1000, calculateRespBO.getItems().get(0).getPrice());
  92 + assertEquals(0, calculateRespBO.getItems().get(0).getDiscountPrice());
  93 + assertEquals(0, calculateRespBO.getItems().get(0).getDeliveryPrice());
  94 + assertEquals(0, calculateRespBO.getItems().get(0).getCouponPrice());
  95 + assertEquals(0, calculateRespBO.getItems().get(0).getPointPrice());
  96 + assertEquals(1000, calculateRespBO.getItems().get(0).getPayPrice());
  97 + assertEquals("小菜", calculateRespBO.getItems().get(0).getSpuName());
  98 + assertEquals("https://t.cn/1.png", calculateRespBO.getItems().get(0).getPicUrl());
  99 + assertEquals(666L, calculateRespBO.getItems().get(0).getCategoryId());
  100 + assertEquals(skuList.get(0).getProperties(), calculateRespBO.getItems().get(0).getProperties());
  101 + // 断言:SKU 2
  102 + assertEquals(1001L, calculateRespBO.getItems().get(1).getSpuId());
  103 + assertEquals(200L, calculateRespBO.getItems().get(1).getSkuId());
  104 + assertEquals(3, calculateRespBO.getItems().get(1).getCount());
  105 + assertNull(calculateRespBO.getItems().get(1).getCartId());
  106 + assertTrue(calculateRespBO.getItems().get(1).getSelected());
  107 + assertEquals(2000, calculateRespBO.getItems().get(1).getPrice());
  108 + assertEquals(0, calculateRespBO.getItems().get(1).getDiscountPrice());
  109 + assertEquals(0, calculateRespBO.getItems().get(1).getDeliveryPrice());
  110 + assertEquals(0, calculateRespBO.getItems().get(1).getCouponPrice());
  111 + assertEquals(0, calculateRespBO.getItems().get(1).getPointPrice());
  112 + assertEquals(6000, calculateRespBO.getItems().get(1).getPayPrice());
  113 + assertEquals("小菜", calculateRespBO.getItems().get(1).getSpuName());
  114 + assertEquals("https://t.cn/2.png", calculateRespBO.getItems().get(1).getPicUrl());
  115 + assertEquals(666L, calculateRespBO.getItems().get(1).getCategoryId());
  116 + assertEquals(skuList.get(1).getProperties(), calculateRespBO.getItems().get(1).getProperties());
  117 + // 断言:SKU 3
  118 + assertEquals(1001L, calculateRespBO.getItems().get(2).getSpuId());
  119 + assertEquals(300L, calculateRespBO.getItems().get(2).getSkuId());
  120 + assertEquals(6, calculateRespBO.getItems().get(2).getCount());
  121 + assertEquals(233L, calculateRespBO.getItems().get(2).getCartId());
  122 + assertFalse(calculateRespBO.getItems().get(2).getSelected());
  123 + assertEquals(3000, calculateRespBO.getItems().get(2).getPrice());
  124 + assertEquals(0, calculateRespBO.getItems().get(2).getDiscountPrice());
  125 + assertEquals(0, calculateRespBO.getItems().get(2).getDeliveryPrice());
  126 + assertEquals(0, calculateRespBO.getItems().get(2).getCouponPrice());
  127 + assertEquals(0, calculateRespBO.getItems().get(2).getPointPrice());
  128 + assertEquals(18000, calculateRespBO.getItems().get(2).getPayPrice());
  129 + assertEquals("小菜", calculateRespBO.getItems().get(2).getSpuName());
  130 + assertEquals("https://t.cn/3.png", calculateRespBO.getItems().get(2).getPicUrl());
  131 + assertEquals(666L, calculateRespBO.getItems().get(2).getCategoryId());
  132 + assertEquals(skuList.get(2).getProperties(), calculateRespBO.getItems().get(2).getProperties());
  133 + }
  134 +
  135 +}
... ...
yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeCouponPriceCalculatorTest.java 0 → 100644
  1 +package cn.iocoder.yudao.module.trade.service.price.calculator;
  2 +
  3 +import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest;
  4 +import cn.iocoder.yudao.module.promotion.api.coupon.CouponApi;
  5 +import cn.iocoder.yudao.module.promotion.api.coupon.dto.CouponRespDTO;
  6 +import cn.iocoder.yudao.module.promotion.api.coupon.dto.CouponValidReqDTO;
  7 +import cn.iocoder.yudao.module.promotion.enums.common.PromotionDiscountTypeEnum;
  8 +import cn.iocoder.yudao.module.promotion.enums.common.PromotionProductScopeEnum;
  9 +import cn.iocoder.yudao.module.promotion.enums.common.PromotionTypeEnum;
  10 +import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateReqBO;
  11 +import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateRespBO;
  12 +import org.junit.jupiter.api.Test;
  13 +import org.mockito.InjectMocks;
  14 +import org.mockito.Mock;
  15 +
  16 +import java.util.ArrayList;
  17 +
  18 +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo;
  19 +import static java.util.Arrays.asList;
  20 +import static org.junit.jupiter.api.Assertions.assertEquals;
  21 +import static org.junit.jupiter.api.Assertions.assertTrue;
  22 +import static org.mockito.ArgumentMatchers.eq;
  23 +import static org.mockito.Mockito.when;
  24 +
  25 +/**
  26 + * {@link TradeCouponPriceCalculator} 的单元测试类
  27 + *
  28 + * @author 芋道源码
  29 + */
  30 +class TradeCouponPriceCalculatorTest extends BaseMockitoUnitTest {
  31 +
  32 + @InjectMocks
  33 + private TradeCouponPriceCalculator tradeCouponPriceCalculator;
  34 +
  35 + @Mock
  36 + private CouponApi couponApi;
  37 +
  38 + @Test
  39 + void calculate() {
  40 + // 准备参数
  41 + TradePriceCalculateReqBO param = new TradePriceCalculateReqBO()
  42 + .setUserId(233L).setCouponId(1024L)
  43 + .setItems(asList(
  44 + new TradePriceCalculateReqBO.Item().setSkuId(10L).setCount(2).setSelected(true), // 匹配优惠劵
  45 + new TradePriceCalculateReqBO.Item().setSkuId(20L).setCount(3).setSelected(true), // 匹配优惠劵
  46 + new TradePriceCalculateReqBO.Item().setSkuId(30L).setCount(4).setSelected(true), // 不匹配优惠劵
  47 + new TradePriceCalculateReqBO.Item().setSkuId(40L).setCount(5).setSelected(false) // 匹配优惠劵,但是未选中
  48 + ));
  49 + TradePriceCalculateRespBO result = new TradePriceCalculateRespBO()
  50 + .setPrice(new TradePriceCalculateRespBO.Price())
  51 + .setPromotions(new ArrayList<>())
  52 + .setItems(asList(
  53 + new TradePriceCalculateRespBO.OrderItem().setSkuId(10L).setCount(2).setSelected(true)
  54 + .setPrice(100).setSpuId(1L),
  55 + new TradePriceCalculateRespBO.OrderItem().setSkuId(20L).setCount(3).setSelected(true)
  56 + .setPrice(50).setSpuId(2L),
  57 + new TradePriceCalculateRespBO.OrderItem().setSkuId(30L).setCount(4).setSelected(true)
  58 + .setPrice(30).setSpuId(3L),
  59 + new TradePriceCalculateRespBO.OrderItem().setSkuId(40L).setCount(5).setSelected(false)
  60 + .setPrice(60).setSpuId(1L)
  61 + ));
  62 + // 保证价格被初始化上
  63 + TradePriceCalculatorHelper.recountPayPrice(result.getItems());
  64 + TradePriceCalculatorHelper.recountAllPrice(result);
  65 +
  66 + // mock 方法(优惠劵 Coupon 信息)
  67 + CouponRespDTO coupon = randomPojo(CouponRespDTO.class, o -> o.setId(1024L).setName("程序员节")
  68 + .setProductScope(PromotionProductScopeEnum.SPU.getScope()).setProductSpuIds(asList(1L, 2L))
  69 + .setUsePrice(350).setDiscountType(PromotionDiscountTypeEnum.PERCENT.getType())
  70 + .setDiscountPercent(50).setDiscountLimitPrice(70));
  71 + when(couponApi.validateCoupon(eq(new CouponValidReqDTO().setId(1024L).setUserId(233L)))).thenReturn(coupon);
  72 +
  73 + // 调用
  74 + tradeCouponPriceCalculator.calculate(param, result);
  75 + // 断言
  76 + assertEquals(result.getCouponId(), 1024L);
  77 + // 断言:Price 部分
  78 + TradePriceCalculateRespBO.Price price = result.getPrice();
  79 + assertEquals(price.getTotalPrice(), 470);
  80 + assertEquals(price.getDiscountPrice(), 0);
  81 + assertEquals(price.getPointPrice(), 0);
  82 + assertEquals(price.getDeliveryPrice(), 0);
  83 + assertEquals(price.getCouponPrice(), 70);
  84 + assertEquals(price.getPayPrice(), 400);
  85 + // 断言:SKU 1
  86 + TradePriceCalculateRespBO.OrderItem orderItem01 = result.getItems().get(0);
  87 + assertEquals(orderItem01.getSkuId(), 10L);
  88 + assertEquals(orderItem01.getCount(), 2);
  89 + assertEquals(orderItem01.getPrice(), 100);
  90 + assertEquals(orderItem01.getDiscountPrice(), 0);
  91 + assertEquals(orderItem01.getDeliveryPrice(), 0);
  92 + assertEquals(orderItem01.getCouponPrice(), 40);
  93 + assertEquals(orderItem01.getPointPrice(), 0);
  94 + assertEquals(orderItem01.getPayPrice(), 160);
  95 + // 断言:SKU 2
  96 + TradePriceCalculateRespBO.OrderItem orderItem02 = result.getItems().get(1);
  97 + assertEquals(orderItem02.getSkuId(), 20L);
  98 + assertEquals(orderItem02.getCount(), 3);
  99 + assertEquals(orderItem02.getPrice(), 50);
  100 + assertEquals(orderItem02.getDiscountPrice(), 0);
  101 + assertEquals(orderItem02.getDeliveryPrice(), 0);
  102 + assertEquals(orderItem02.getCouponPrice(), 30);
  103 + assertEquals(orderItem02.getPointPrice(), 0);
  104 + assertEquals(orderItem02.getPayPrice(), 120);
  105 + // 断言:SKU 3
  106 + TradePriceCalculateRespBO.OrderItem orderItem03 = result.getItems().get(2);
  107 + assertEquals(orderItem03.getSkuId(), 30L);
  108 + assertEquals(orderItem03.getCount(), 4);
  109 + assertEquals(orderItem03.getPrice(), 30);
  110 + assertEquals(orderItem03.getDiscountPrice(), 0);
  111 + assertEquals(orderItem03.getCouponPrice(), 0);
  112 + assertEquals(orderItem03.getPointPrice(), 0);
  113 + assertEquals(orderItem03.getPayPrice(), 120);
  114 + // 断言:SKU 4
  115 + TradePriceCalculateRespBO.OrderItem orderItem04 = result.getItems().get(3);
  116 + assertEquals(orderItem04.getSkuId(), 40L);
  117 + assertEquals(orderItem04.getCount(), 5);
  118 + assertEquals(orderItem04.getPrice(), 60);
  119 + assertEquals(orderItem04.getDiscountPrice(), 0);
  120 + assertEquals(orderItem04.getCouponPrice(), 0);
  121 + assertEquals(orderItem04.getPointPrice(), 0);
  122 + assertEquals(orderItem04.getPayPrice(), 300);
  123 + // 断言 Promotion 部分
  124 + assertEquals(result.getPromotions().size(), 1);
  125 + TradePriceCalculateRespBO.Promotion promotion01 = result.getPromotions().get(0);
  126 + assertEquals(promotion01.getId(), 1024L);
  127 + assertEquals(promotion01.getName(), "程序员节");
  128 + assertEquals(promotion01.getType(), PromotionTypeEnum.COUPON.getType());
  129 + assertEquals(promotion01.getTotalPrice(), 350);
  130 + assertEquals(promotion01.getDiscountPrice(), 70);
  131 + assertTrue(promotion01.getMatch());
  132 + assertEquals(promotion01.getDescription(), "优惠劵:省 0.70 元");
  133 + assertEquals(promotion01.getItems().size(), 2);
  134 + TradePriceCalculateRespBO.PromotionItem promotionItem011 = promotion01.getItems().get(0);
  135 + assertEquals(promotionItem011.getSkuId(), 10L);
  136 + assertEquals(promotionItem011.getTotalPrice(), 200);
  137 + assertEquals(promotionItem011.getDiscountPrice(), 40);
  138 + TradePriceCalculateRespBO.PromotionItem promotionItem012 = promotion01.getItems().get(1);
  139 + assertEquals(promotionItem012.getSkuId(), 20L);
  140 + assertEquals(promotionItem012.getTotalPrice(), 150);
  141 + assertEquals(promotionItem012.getDiscountPrice(), 30);
  142 + }
  143 +}
... ...