mirror of
				https://github.com/YunaiV/ruoyi-vue-pro.git
				synced 2025-10-31 10:37:41 +08:00 
			
		
		
		
	mall + trade:增肌爱 TradeCouponPriceCalculator 的单元测试
This commit is contained in:
		| @ -51,10 +51,6 @@ public class ProductSkuRespDTO { | |||||||
|      * 库存 |      * 库存 | ||||||
|      */ |      */ | ||||||
|     private Integer stock; |     private Integer stock; | ||||||
|     /** |  | ||||||
|      * 预警预存 |  | ||||||
|      */ |  | ||||||
|     private Integer warnStock; |  | ||||||
|     /** |     /** | ||||||
|      * 商品重量,单位:kg 千克 |      * 商品重量,单位:kg 千克 | ||||||
|      */ |      */ | ||||||
|  | |||||||
| @ -12,6 +12,7 @@ import java.util.List; | |||||||
|  * @author 芋道源码 |  * @author 芋道源码 | ||||||
|  */ |  */ | ||||||
| @Data | @Data | ||||||
|  | @Deprecated | ||||||
| public class PriceCalculateReqDTO { | public class PriceCalculateReqDTO { | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|  | |||||||
| @ -56,54 +56,6 @@ public class PriceServiceTest extends BaseMockitoUnitTest { | |||||||
|     @Mock |     @Mock | ||||||
|     private ProductSkuApi productSkuApi; |     private ProductSkuApi productSkuApi; | ||||||
|  |  | ||||||
|     @Test |  | ||||||
|     public void testCalculatePrice_memberDiscount() { |  | ||||||
|         // 准备参数 |  | ||||||
|         // TODO 芋艿:userId = 1,实现 9 折;后续改成 mock |  | ||||||
|         PriceCalculateReqDTO calculateReqDTO = new PriceCalculateReqDTO().setUserId(1L) |  | ||||||
|                 .setItems(singletonList(new PriceCalculateReqDTO.Item().setSkuId(10L).setCount(2))); |  | ||||||
|         // mock 方法(商品 SKU 信息) |  | ||||||
|         ProductSkuRespDTO productSku = randomPojo(ProductSkuRespDTO.class, o -> o.setId(10L).setPrice(100)); |  | ||||||
|         when(productSkuApi.getSkuList(eq(asSet(10L)))).thenReturn(singletonList(productSku)); |  | ||||||
|  |  | ||||||
|         // 调用 |  | ||||||
|         PriceCalculateRespDTO priceCalculate = priceService.calculatePrice(calculateReqDTO); |  | ||||||
|         // 断言 Order 部分 |  | ||||||
|         PriceCalculateRespDTO.Order order = priceCalculate.getOrder(); |  | ||||||
|         assertEquals(order.getTotalPrice(), 200); |  | ||||||
|         assertEquals(order.getDiscountPrice(), 0); |  | ||||||
|         assertEquals(order.getPointPrice(), 0); |  | ||||||
|         assertEquals(order.getDeliveryPrice(), 0); |  | ||||||
|         assertEquals(order.getPayPrice(), 180); |  | ||||||
|         assertNull(order.getCouponId()); |  | ||||||
|         // 断言 OrderItem 部分 |  | ||||||
|         assertEquals(order.getItems().size(), 1); |  | ||||||
|         PriceCalculateRespDTO.OrderItem orderItem = order.getItems().get(0); |  | ||||||
|         assertEquals(orderItem.getSkuId(), 10L); |  | ||||||
|         assertEquals(orderItem.getCount(), 2); |  | ||||||
|         assertEquals(orderItem.getOriginalPrice(), 200); |  | ||||||
|         assertEquals(orderItem.getOriginalUnitPrice(), 100); |  | ||||||
|         assertEquals(orderItem.getDiscountPrice(), 20); |  | ||||||
|         assertEquals(orderItem.getPayPrice(), 180); |  | ||||||
|         assertEquals(orderItem.getOrderPartPrice(), 0); |  | ||||||
|         assertEquals(orderItem.getOrderDividePrice(), 180); |  | ||||||
|         // 断言 Promotion 部分 |  | ||||||
|         assertEquals(priceCalculate.getPromotions().size(), 1); |  | ||||||
|         PriceCalculateRespDTO.Promotion promotion = priceCalculate.getPromotions().get(0); |  | ||||||
|         assertNull(promotion.getId()); |  | ||||||
|         assertEquals(promotion.getName(), "会员折扣"); |  | ||||||
|         assertEquals(promotion.getType(), PromotionTypeEnum.MEMBER.getType()); |  | ||||||
|         assertEquals(promotion.getTotalPrice(), 200); |  | ||||||
|         assertEquals(promotion.getDiscountPrice(), 20); |  | ||||||
|         assertTrue(promotion.getMatch()); |  | ||||||
|         assertEquals(promotion.getDescription(), "会员折扣:省 0.20 元"); |  | ||||||
|         PriceCalculateRespDTO.PromotionItem promotionItem = promotion.getItems().get(0); |  | ||||||
|         assertEquals(promotion.getItems().size(), 1); |  | ||||||
|         assertEquals(promotionItem.getSkuId(), 10L); |  | ||||||
|         assertEquals(promotionItem.getOriginalPrice(), 200); |  | ||||||
|         assertEquals(promotionItem.getDiscountPrice(), 20); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     @Test |     @Test | ||||||
|     public void testCalculatePrice_discountActivity() { |     public void testCalculatePrice_discountActivity() { | ||||||
|         // 准备参数 |         // 准备参数 | ||||||
| @ -364,87 +316,6 @@ public class PriceServiceTest extends BaseMockitoUnitTest { | |||||||
|         assertEquals(promotionItem012.getDiscountPrice(), 0); |         assertEquals(promotionItem012.getDiscountPrice(), 0); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Test |  | ||||||
|     public void testCalculatePrice_coupon() { |  | ||||||
|         // 准备参数 |  | ||||||
|         PriceCalculateReqDTO calculateReqDTO = new PriceCalculateReqDTO().setUserId(randomLongId()) |  | ||||||
|                 .setItems(asList(new PriceCalculateReqDTO.Item().setSkuId(10L).setCount(2), |  | ||||||
|                         new PriceCalculateReqDTO.Item().setSkuId(20L).setCount(3), |  | ||||||
|                         new PriceCalculateReqDTO.Item().setSkuId(30L).setCount(4))) |  | ||||||
|                 .setCouponId(1024L); |  | ||||||
|         // mock 方法(商品 SKU 信息) |  | ||||||
|         ProductSkuRespDTO productSku01 = randomPojo(ProductSkuRespDTO.class, o -> o.setId(10L).setPrice(100).setSpuId(1L)); |  | ||||||
|         ProductSkuRespDTO productSku02 = randomPojo(ProductSkuRespDTO.class, o -> o.setId(20L).setPrice(50).setSpuId(2L)); |  | ||||||
|         ProductSkuRespDTO productSku03 = randomPojo(ProductSkuRespDTO.class, o -> o.setId(30L).setPrice(30).setSpuId(3L)); |  | ||||||
|         when(productSkuApi.getSkuList(eq(asSet(10L, 20L, 30L)))).thenReturn(asList(productSku01, productSku02, productSku03)); |  | ||||||
|         // mock 方法(优惠劵 Coupon 信息) |  | ||||||
|         CouponDO coupon = randomPojo(CouponDO.class, o -> o.setId(1024L).setName("程序员节") |  | ||||||
|                 .setProductScope(PromotionProductScopeEnum.SPU.getScope()).setProductSpuIds(asList(1L, 2L)) |  | ||||||
|                 .setUsePrice(350).setDiscountType(PromotionDiscountTypeEnum.PERCENT.getType()) |  | ||||||
|                 .setDiscountPercent(50).setDiscountLimitPrice(70)); |  | ||||||
|         when(couponService.validCoupon(eq(1024L), eq(calculateReqDTO.getUserId()))).thenReturn(coupon); |  | ||||||
|  |  | ||||||
|         // 调用 |  | ||||||
|         PriceCalculateRespDTO priceCalculate = priceService.calculatePrice(calculateReqDTO); |  | ||||||
|         // 断言 Order 部分 |  | ||||||
|         PriceCalculateRespDTO.Order order = priceCalculate.getOrder(); |  | ||||||
|         assertEquals(order.getTotalPrice(), 470); |  | ||||||
|         assertEquals(order.getDiscountPrice(), 0); |  | ||||||
|         assertEquals(order.getPointPrice(), 0); |  | ||||||
|         assertEquals(order.getDeliveryPrice(), 0); |  | ||||||
|         assertEquals(order.getPayPrice(), 400); |  | ||||||
|         assertEquals(order.getCouponId(), 1024L); |  | ||||||
|         assertEquals(order.getCouponPrice(), 70); |  | ||||||
|         // 断言 OrderItem 部分 |  | ||||||
|         assertEquals(order.getItems().size(), 3); |  | ||||||
|         PriceCalculateRespDTO.OrderItem orderItem01 = order.getItems().get(0); |  | ||||||
|         assertEquals(orderItem01.getSkuId(), 10L); |  | ||||||
|         assertEquals(orderItem01.getCount(), 2); |  | ||||||
|         assertEquals(orderItem01.getOriginalPrice(), 200); |  | ||||||
|         assertEquals(orderItem01.getOriginalUnitPrice(), 100); |  | ||||||
|         assertEquals(orderItem01.getDiscountPrice(), 0); |  | ||||||
|         assertEquals(orderItem01.getPayPrice(), 200); |  | ||||||
|         assertEquals(orderItem01.getOrderPartPrice(), 40); |  | ||||||
|         assertEquals(orderItem01.getOrderDividePrice(), 160); |  | ||||||
|         PriceCalculateRespDTO.OrderItem orderItem02 = order.getItems().get(1); |  | ||||||
|         assertEquals(orderItem02.getSkuId(), 20L); |  | ||||||
|         assertEquals(orderItem02.getCount(), 3); |  | ||||||
|         assertEquals(orderItem02.getOriginalPrice(), 150); |  | ||||||
|         assertEquals(orderItem02.getOriginalUnitPrice(), 50); |  | ||||||
|         assertEquals(orderItem02.getDiscountPrice(), 0); |  | ||||||
|         assertEquals(orderItem02.getPayPrice(), 150); |  | ||||||
|         assertEquals(orderItem02.getOrderPartPrice(), 30); |  | ||||||
|         assertEquals(orderItem02.getOrderDividePrice(), 120); |  | ||||||
|         PriceCalculateRespDTO.OrderItem orderItem03 = order.getItems().get(2); |  | ||||||
|         assertEquals(orderItem03.getSkuId(), 30L); |  | ||||||
|         assertEquals(orderItem03.getCount(), 4); |  | ||||||
|         assertEquals(orderItem03.getOriginalPrice(), 120); |  | ||||||
|         assertEquals(orderItem03.getOriginalUnitPrice(), 30); |  | ||||||
|         assertEquals(orderItem03.getDiscountPrice(), 0); |  | ||||||
|         assertEquals(orderItem03.getPayPrice(), 120); |  | ||||||
|         assertEquals(orderItem03.getOrderPartPrice(), 0); |  | ||||||
|         assertEquals(orderItem03.getOrderDividePrice(), 120); |  | ||||||
|         // 断言 Promotion 部分 |  | ||||||
|         assertEquals(priceCalculate.getPromotions().size(), 1); |  | ||||||
|         PriceCalculateRespDTO.Promotion promotion01 = priceCalculate.getPromotions().get(0); |  | ||||||
|         assertEquals(promotion01.getId(), 1024L); |  | ||||||
|         assertEquals(promotion01.getName(), "程序员节"); |  | ||||||
|         assertEquals(promotion01.getType(), PromotionTypeEnum.COUPON.getType()); |  | ||||||
|         assertEquals(promotion01.getTotalPrice(), 350); |  | ||||||
|         assertEquals(promotion01.getDiscountPrice(), 70); |  | ||||||
|         assertTrue(promotion01.getMatch()); |  | ||||||
|         assertEquals(promotion01.getDescription(), "优惠劵:省 0.70 元"); |  | ||||||
|         assertEquals(promotion01.getItems().size(), 2); |  | ||||||
|         PriceCalculateRespDTO.PromotionItem promotionItem011 = promotion01.getItems().get(0); |  | ||||||
|         assertEquals(promotionItem011.getSkuId(), 10L); |  | ||||||
|         assertEquals(promotionItem011.getOriginalPrice(), 200); |  | ||||||
|         assertEquals(promotionItem011.getDiscountPrice(), 40); |  | ||||||
|         PriceCalculateRespDTO.PromotionItem promotionItem012 = promotion01.getItems().get(1); |  | ||||||
|         assertEquals(promotionItem012.getSkuId(), 20L); |  | ||||||
|         assertEquals(promotionItem012.getOriginalPrice(), 150); |  | ||||||
|         assertEquals(promotionItem012.getDiscountPrice(), 30); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     @Test |     @Test | ||||||
|     public void testGetMeetCouponList() { |     public void testGetMeetCouponList() { | ||||||
|         // 准备参数 |         // 准备参数 | ||||||
|  | |||||||
| @ -101,7 +101,8 @@ public class TradeCouponPriceCalculator implements TradePriceCalculator { | |||||||
|                                                                                   CouponRespDTO coupon) { |                                                                                   CouponRespDTO coupon) { | ||||||
|         Predicate<TradePriceCalculateRespBO.OrderItem> matchPredicate = TradePriceCalculateRespBO.OrderItem::getSelected; |         Predicate<TradePriceCalculateRespBO.OrderItem> matchPredicate = TradePriceCalculateRespBO.OrderItem::getSelected; | ||||||
|         if (PromotionProductScopeEnum.SPU.getScope().equals(coupon.getProductScope())) { |         if (PromotionProductScopeEnum.SPU.getScope().equals(coupon.getProductScope())) { | ||||||
|             matchPredicate = orderItem -> coupon.getProductSpuIds().contains(orderItem.getSpuId()); |             matchPredicate = matchPredicate // 额外加如下条件 | ||||||
|  |                     .and(orderItem -> coupon.getProductSpuIds().contains(orderItem.getSpuId())); | ||||||
|         } |         } | ||||||
|         return filterList(result.getItems(), matchPredicate); |         return filterList(result.getItems(), matchPredicate); | ||||||
|     } |     } | ||||||
|  | |||||||
| @ -15,8 +15,6 @@ import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils. | |||||||
| import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.getSumValue; | import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.getSumValue; | ||||||
| import static java.util.Collections.singletonList; | import static java.util.Collections.singletonList; | ||||||
|  |  | ||||||
| // TODO 芋艿:改成父类 |  | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * {@link TradePriceCalculator} 的工具类 |  * {@link TradePriceCalculator} 的工具类 | ||||||
|  * |  * | ||||||
| @ -106,6 +104,31 @@ public class TradePriceCalculatorHelper { | |||||||
|                 - orderItem.getPointPrice()); |                 - orderItem.getPointPrice()); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * 重新计算每个订单项的支付金额 | ||||||
|  |      * | ||||||
|  |      * 【目前主要是单测使用】 | ||||||
|  |      * | ||||||
|  |      * @param orderItems 订单项数组 | ||||||
|  |      */ | ||||||
|  |     public static void recountPayPrice(List<TradePriceCalculateRespBO.OrderItem> orderItems) { | ||||||
|  |         orderItems.forEach(orderItem -> { | ||||||
|  |             if (orderItem.getDiscountPrice() == null) { | ||||||
|  |                 orderItem.setDiscountPrice(0); | ||||||
|  |             } | ||||||
|  |             if (orderItem.getDeliveryPrice() == null) { | ||||||
|  |                 orderItem.setDeliveryPrice(0); | ||||||
|  |             } | ||||||
|  |             if (orderItem.getCouponPrice() == null) { | ||||||
|  |                 orderItem.setCouponPrice(0); | ||||||
|  |             } | ||||||
|  |             if (orderItem.getPointPrice() == null) { | ||||||
|  |                 orderItem.setPointPrice(0); | ||||||
|  |             } | ||||||
|  |             recountPayPrice(orderItem); | ||||||
|  |         }); | ||||||
|  |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * 计算已选中的订单项,总支付金额 |      * 计算已选中的订单项,总支付金额 | ||||||
|      * |      * | ||||||
|  | |||||||
| @ -53,6 +53,9 @@ public class TradeRewardActivityPriceCalculator implements TradePriceCalculator | |||||||
|         // 1.2 获得最大匹配的满减送活动的规则 |         // 1.2 获得最大匹配的满减送活动的规则 | ||||||
|         RewardActivityMatchRespDTO.Rule rule = getMaxMatchRewardActivityRule(rewardActivity, orderItems); |         RewardActivityMatchRespDTO.Rule rule = getMaxMatchRewardActivityRule(rewardActivity, orderItems); | ||||||
|         if (rule == null) { |         if (rule == null) { | ||||||
|  |             TradePriceCalculatorHelper.addNotMatchPromotion(result, orderItems, | ||||||
|  |                     rewardActivity.getId(), rewardActivity.getName(), PromotionTypeEnum.REWARD_ACTIVITY.getType(), | ||||||
|  |                     getRewardActivityNotMeetTip(rewardActivity)); | ||||||
|             return; |             return; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  | |||||||
| @ -8,6 +8,7 @@ import cn.iocoder.yudao.module.member.api.user.MemberUserApi; | |||||||
| import cn.iocoder.yudao.module.pay.api.order.PayOrderApi; | import cn.iocoder.yudao.module.pay.api.order.PayOrderApi; | ||||||
| import cn.iocoder.yudao.module.pay.api.order.dto.PayOrderRespDTO; | import cn.iocoder.yudao.module.pay.api.order.dto.PayOrderRespDTO; | ||||||
| import cn.iocoder.yudao.module.pay.enums.order.PayOrderStatusEnum; | import cn.iocoder.yudao.module.pay.enums.order.PayOrderStatusEnum; | ||||||
|  | import cn.iocoder.yudao.module.product.api.property.dto.ProductPropertyValueDetailRespDTO; | ||||||
| import cn.iocoder.yudao.module.product.api.sku.ProductSkuApi; | import cn.iocoder.yudao.module.product.api.sku.ProductSkuApi; | ||||||
| import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO; | import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO; | ||||||
| import cn.iocoder.yudao.module.product.api.spu.ProductSpuApi; | import cn.iocoder.yudao.module.product.api.spu.ProductSpuApi; | ||||||
| @ -101,10 +102,10 @@ public class TradeOrderServiceTest extends BaseDbUnitTest { | |||||||
|         // mock 方法(商品 SKU 检查) |         // mock 方法(商品 SKU 检查) | ||||||
|         ProductSkuRespDTO sku01 = randomPojo(ProductSkuRespDTO.class, o -> o.setId(1L).setSpuId(11L) |         ProductSkuRespDTO sku01 = randomPojo(ProductSkuRespDTO.class, o -> o.setId(1L).setSpuId(11L) | ||||||
|                 .setPrice(50).setStock(100) |                 .setPrice(50).setStock(100) | ||||||
|                 .setProperties(singletonList(new ProductSkuRespDTO.Property().setPropertyId(111L).setValueId(222L)))); |                 .setProperties(singletonList(new ProductPropertyValueDetailRespDTO().setPropertyId(111L).setValueId(222L)))); | ||||||
|         ProductSkuRespDTO sku02 = randomPojo(ProductSkuRespDTO.class, o -> o.setId(2L).setSpuId(21L) |         ProductSkuRespDTO sku02 = randomPojo(ProductSkuRespDTO.class, o -> o.setId(2L).setSpuId(21L) | ||||||
|                 .setPrice(20).setStock(50)) |                 .setPrice(20).setStock(50)) | ||||||
|                 .setProperties(singletonList(new ProductSkuRespDTO.Property().setPropertyId(333L).setValueId(444L))); |                 .setProperties(singletonList(new ProductPropertyValueDetailRespDTO().setPropertyId(333L).setValueId(444L))); | ||||||
|         when(productSkuApi.getSkuList(eq(asSet(1L, 2L)))).thenReturn(Arrays.asList(sku01, sku02)); |         when(productSkuApi.getSkuList(eq(asSet(1L, 2L)))).thenReturn(Arrays.asList(sku01, sku02)); | ||||||
|         // mock 方法(商品 SPU 检查) |         // mock 方法(商品 SPU 检查) | ||||||
|         ProductSpuRespDTO spu01 = randomPojo(ProductSpuRespDTO.class, o -> o.setId(11L) |         ProductSpuRespDTO spu01 = randomPojo(ProductSpuRespDTO.class, o -> o.setId(11L) | ||||||
| @ -114,7 +115,7 @@ public class TradeOrderServiceTest extends BaseDbUnitTest { | |||||||
|         when(productSpuApi.getSpuList(eq(asSet(11L, 21L)))).thenReturn(Arrays.asList(spu01, spu02)); |         when(productSpuApi.getSpuList(eq(asSet(11L, 21L)))).thenReturn(Arrays.asList(spu01, spu02)); | ||||||
|         // mock 方法(用户收件地址的校验) |         // mock 方法(用户收件地址的校验) | ||||||
|         AddressRespDTO addressRespDTO = new AddressRespDTO().setId(10L).setUserId(userId).setName("芋艿") |         AddressRespDTO addressRespDTO = new AddressRespDTO().setId(10L).setUserId(userId).setName("芋艿") | ||||||
|                 .setMobile("15601691300").setAreaId(3306L).setPostCode("85757").setDetailAddress("土豆村"); |                 .setMobile("15601691300").setAreaId(3306).setPostCode("85757").setDetailAddress("土豆村"); | ||||||
|         when(addressApi.getAddress(eq(10L), eq(userId))).thenReturn(addressRespDTO); |         when(addressApi.getAddress(eq(10L), eq(userId))).thenReturn(addressRespDTO); | ||||||
|         // mock 方法(价格计算) |         // mock 方法(价格计算) | ||||||
|         PriceCalculateRespDTO.OrderItem priceOrderItem01 = new PriceCalculateRespDTO.OrderItem() |         PriceCalculateRespDTO.OrderItem priceOrderItem01 = new PriceCalculateRespDTO.OrderItem() | ||||||
|  | |||||||
| @ -0,0 +1,135 @@ | |||||||
|  | package cn.iocoder.yudao.module.trade.service.price; | ||||||
|  |  | ||||||
|  | import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest; | ||||||
|  | import cn.iocoder.yudao.module.product.api.property.dto.ProductPropertyValueDetailRespDTO; | ||||||
|  | import cn.iocoder.yudao.module.product.api.sku.ProductSkuApi; | ||||||
|  | import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO; | ||||||
|  | import cn.iocoder.yudao.module.product.api.spu.ProductSpuApi; | ||||||
|  | import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO; | ||||||
|  | import cn.iocoder.yudao.module.product.enums.spu.ProductSpuStatusEnum; | ||||||
|  | import cn.iocoder.yudao.module.trade.enums.order.TradeOrderTypeEnum; | ||||||
|  | import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateReqBO; | ||||||
|  | import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateRespBO; | ||||||
|  | import cn.iocoder.yudao.module.trade.service.price.calculator.TradePriceCalculator; | ||||||
|  | import org.junit.jupiter.api.Test; | ||||||
|  | import org.mockito.InjectMocks; | ||||||
|  | import org.mockito.Mock; | ||||||
|  | import org.mockito.Mockito; | ||||||
|  |  | ||||||
|  | import java.util.Arrays; | ||||||
|  | import java.util.List; | ||||||
|  |  | ||||||
|  | import static cn.iocoder.yudao.framework.common.util.collection.SetUtils.asSet; | ||||||
|  | import static java.util.Collections.singletonList; | ||||||
|  | import static org.junit.jupiter.api.Assertions.*; | ||||||
|  | import static org.mockito.Mockito.when; | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * {@link TradePriceServiceImpl} 的单元测试 | ||||||
|  |  * | ||||||
|  |  * @author 芋道源码 | ||||||
|  |  */ | ||||||
|  | public class TradePriceServiceImplTest extends BaseMockitoUnitTest { | ||||||
|  |  | ||||||
|  |     @InjectMocks | ||||||
|  |     private TradePriceServiceImpl tradePriceService; | ||||||
|  |  | ||||||
|  |     @Mock | ||||||
|  |     private ProductSkuApi productSkuApi; | ||||||
|  |     @Mock | ||||||
|  |     private ProductSpuApi productSpuApi; | ||||||
|  |     @Mock | ||||||
|  |     private List<TradePriceCalculator> priceCalculators; | ||||||
|  |  | ||||||
|  |     @Test | ||||||
|  |     public void testCalculatePrice() { | ||||||
|  |         // 准备参数 | ||||||
|  |         TradePriceCalculateReqBO calculateReqBO = new TradePriceCalculateReqBO() | ||||||
|  |                 .setType(TradeOrderTypeEnum.NORMAL.getType()).setUserId(10L) | ||||||
|  |                 .setCouponId(20L).setAddressId(30L) | ||||||
|  |                 .setItems(Arrays.asList( | ||||||
|  |                         new TradePriceCalculateReqBO.Item().setSkuId(100L).setCount(1).setSelected(true), | ||||||
|  |                         new TradePriceCalculateReqBO.Item().setSkuId(200L).setCount(3).setSelected(true), | ||||||
|  |                         new TradePriceCalculateReqBO.Item().setSkuId(300L).setCount(6).setCartId(233L).setSelected(false) | ||||||
|  |                 )); | ||||||
|  |         // mock 方法 | ||||||
|  |         List<ProductSkuRespDTO> skuList = Arrays.asList( | ||||||
|  |                 new ProductSkuRespDTO().setId(100L).setStock(500).setPrice(1000).setPicUrl("https://t.cn/1.png").setSpuId(1001L) | ||||||
|  |                         .setProperties(singletonList(new ProductPropertyValueDetailRespDTO().setPropertyId(1L).setPropertyName("颜色") | ||||||
|  |                                 .setValueId(2L).setValueName("红色"))), | ||||||
|  |                 new ProductSkuRespDTO().setId(200L).setStock(400).setPrice(2000).setPicUrl("https://t.cn/2.png").setSpuId(1001L) | ||||||
|  |                         .setProperties(singletonList(new ProductPropertyValueDetailRespDTO().setPropertyId(1L).setPropertyName("颜色") | ||||||
|  |                                 .setValueId(3L).setValueName("黄色"))), | ||||||
|  |                 new ProductSkuRespDTO().setId(300L).setStock(600).setPrice(3000).setPicUrl("https://t.cn/3.png").setSpuId(1001L) | ||||||
|  |                         .setProperties(singletonList(new ProductPropertyValueDetailRespDTO().setPropertyId(1L).setPropertyName("颜色") | ||||||
|  |                                 .setValueId(4L).setValueName("黑色"))) | ||||||
|  |         ); | ||||||
|  |         when(productSkuApi.getSkuList(Mockito.eq(asSet(100L, 200L, 300L)))).thenReturn(skuList); | ||||||
|  |         when(productSpuApi.getSpuList(Mockito.eq(asSet(1001L)))) | ||||||
|  |                 .thenReturn(singletonList(new ProductSpuRespDTO().setId(1001L).setName("小菜").setCategoryId(666L) | ||||||
|  |                         .setStatus(ProductSpuStatusEnum.ENABLE.getStatus()))); | ||||||
|  |  | ||||||
|  |         // 调用 | ||||||
|  |         TradePriceCalculateRespBO calculateRespBO = tradePriceService.calculatePrice(calculateReqBO); | ||||||
|  |         // 断言 | ||||||
|  |         assertEquals(TradeOrderTypeEnum.NORMAL.getType(), calculateRespBO.getType()); | ||||||
|  |         assertEquals(0, calculateRespBO.getPromotions().size()); | ||||||
|  |         assertNull(calculateRespBO.getCouponId()); | ||||||
|  |         // 断言:订单价格 | ||||||
|  |         assertEquals(7000, calculateRespBO.getPrice().getTotalPrice()); | ||||||
|  |         assertEquals(0, calculateRespBO.getPrice().getDiscountPrice()); | ||||||
|  |         assertEquals(0, calculateRespBO.getPrice().getDeliveryPrice()); | ||||||
|  |         assertEquals(0, calculateRespBO.getPrice().getCouponPrice()); | ||||||
|  |         assertEquals(0, calculateRespBO.getPrice().getPointPrice()); | ||||||
|  |         assertEquals(7000, calculateRespBO.getPrice().getPayPrice()); | ||||||
|  |         // 断言:SKU 1 | ||||||
|  |         assertEquals(1001L, calculateRespBO.getItems().get(0).getSpuId()); | ||||||
|  |         assertEquals(100L, calculateRespBO.getItems().get(0).getSkuId()); | ||||||
|  |         assertEquals(1, calculateRespBO.getItems().get(0).getCount()); | ||||||
|  |         assertNull(calculateRespBO.getItems().get(0).getCartId()); | ||||||
|  |         assertTrue(calculateRespBO.getItems().get(0).getSelected()); | ||||||
|  |         assertEquals(1000, calculateRespBO.getItems().get(0).getPrice()); | ||||||
|  |         assertEquals(0, calculateRespBO.getItems().get(0).getDiscountPrice()); | ||||||
|  |         assertEquals(0, calculateRespBO.getItems().get(0).getDeliveryPrice()); | ||||||
|  |         assertEquals(0, calculateRespBO.getItems().get(0).getCouponPrice()); | ||||||
|  |         assertEquals(0, calculateRespBO.getItems().get(0).getPointPrice()); | ||||||
|  |         assertEquals(1000, calculateRespBO.getItems().get(0).getPayPrice()); | ||||||
|  |         assertEquals("小菜", calculateRespBO.getItems().get(0).getSpuName()); | ||||||
|  |         assertEquals("https://t.cn/1.png", calculateRespBO.getItems().get(0).getPicUrl()); | ||||||
|  |         assertEquals(666L, calculateRespBO.getItems().get(0).getCategoryId()); | ||||||
|  |         assertEquals(skuList.get(0).getProperties(), calculateRespBO.getItems().get(0).getProperties()); | ||||||
|  |         // 断言:SKU 2 | ||||||
|  |         assertEquals(1001L, calculateRespBO.getItems().get(1).getSpuId()); | ||||||
|  |         assertEquals(200L, calculateRespBO.getItems().get(1).getSkuId()); | ||||||
|  |         assertEquals(3, calculateRespBO.getItems().get(1).getCount()); | ||||||
|  |         assertNull(calculateRespBO.getItems().get(1).getCartId()); | ||||||
|  |         assertTrue(calculateRespBO.getItems().get(1).getSelected()); | ||||||
|  |         assertEquals(2000, calculateRespBO.getItems().get(1).getPrice()); | ||||||
|  |         assertEquals(0, calculateRespBO.getItems().get(1).getDiscountPrice()); | ||||||
|  |         assertEquals(0, calculateRespBO.getItems().get(1).getDeliveryPrice()); | ||||||
|  |         assertEquals(0, calculateRespBO.getItems().get(1).getCouponPrice()); | ||||||
|  |         assertEquals(0, calculateRespBO.getItems().get(1).getPointPrice()); | ||||||
|  |         assertEquals(6000, calculateRespBO.getItems().get(1).getPayPrice()); | ||||||
|  |         assertEquals("小菜", calculateRespBO.getItems().get(1).getSpuName()); | ||||||
|  |         assertEquals("https://t.cn/2.png", calculateRespBO.getItems().get(1).getPicUrl()); | ||||||
|  |         assertEquals(666L, calculateRespBO.getItems().get(1).getCategoryId()); | ||||||
|  |         assertEquals(skuList.get(1).getProperties(), calculateRespBO.getItems().get(1).getProperties()); | ||||||
|  |         // 断言:SKU 3 | ||||||
|  |         assertEquals(1001L, calculateRespBO.getItems().get(2).getSpuId()); | ||||||
|  |         assertEquals(300L, calculateRespBO.getItems().get(2).getSkuId()); | ||||||
|  |         assertEquals(6, calculateRespBO.getItems().get(2).getCount()); | ||||||
|  |         assertEquals(233L, calculateRespBO.getItems().get(2).getCartId()); | ||||||
|  |         assertFalse(calculateRespBO.getItems().get(2).getSelected()); | ||||||
|  |         assertEquals(3000, calculateRespBO.getItems().get(2).getPrice()); | ||||||
|  |         assertEquals(0, calculateRespBO.getItems().get(2).getDiscountPrice()); | ||||||
|  |         assertEquals(0, calculateRespBO.getItems().get(2).getDeliveryPrice()); | ||||||
|  |         assertEquals(0, calculateRespBO.getItems().get(2).getCouponPrice()); | ||||||
|  |         assertEquals(0, calculateRespBO.getItems().get(2).getPointPrice()); | ||||||
|  |         assertEquals(18000, calculateRespBO.getItems().get(2).getPayPrice()); | ||||||
|  |         assertEquals("小菜", calculateRespBO.getItems().get(2).getSpuName()); | ||||||
|  |         assertEquals("https://t.cn/3.png", calculateRespBO.getItems().get(2).getPicUrl()); | ||||||
|  |         assertEquals(666L, calculateRespBO.getItems().get(2).getCategoryId()); | ||||||
|  |         assertEquals(skuList.get(2).getProperties(), calculateRespBO.getItems().get(2).getProperties()); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | } | ||||||
| @ -0,0 +1,143 @@ | |||||||
|  | package cn.iocoder.yudao.module.trade.service.price.calculator; | ||||||
|  |  | ||||||
|  | import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest; | ||||||
|  | import cn.iocoder.yudao.module.promotion.api.coupon.CouponApi; | ||||||
|  | import cn.iocoder.yudao.module.promotion.api.coupon.dto.CouponRespDTO; | ||||||
|  | import cn.iocoder.yudao.module.promotion.api.coupon.dto.CouponValidReqDTO; | ||||||
|  | import cn.iocoder.yudao.module.promotion.enums.common.PromotionDiscountTypeEnum; | ||||||
|  | import cn.iocoder.yudao.module.promotion.enums.common.PromotionProductScopeEnum; | ||||||
|  | import cn.iocoder.yudao.module.promotion.enums.common.PromotionTypeEnum; | ||||||
|  | import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateReqBO; | ||||||
|  | import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateRespBO; | ||||||
|  | import org.junit.jupiter.api.Test; | ||||||
|  | import org.mockito.InjectMocks; | ||||||
|  | import org.mockito.Mock; | ||||||
|  |  | ||||||
|  | import java.util.ArrayList; | ||||||
|  |  | ||||||
|  | import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo; | ||||||
|  | import static java.util.Arrays.asList; | ||||||
|  | import static org.junit.jupiter.api.Assertions.assertEquals; | ||||||
|  | import static org.junit.jupiter.api.Assertions.assertTrue; | ||||||
|  | import static org.mockito.ArgumentMatchers.eq; | ||||||
|  | import static org.mockito.Mockito.when; | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * {@link TradeCouponPriceCalculator} 的单元测试类 | ||||||
|  |  * | ||||||
|  |  * @author 芋道源码 | ||||||
|  |  */ | ||||||
|  | class TradeCouponPriceCalculatorTest extends BaseMockitoUnitTest { | ||||||
|  |  | ||||||
|  |     @InjectMocks | ||||||
|  |     private TradeCouponPriceCalculator tradeCouponPriceCalculator; | ||||||
|  |  | ||||||
|  |     @Mock | ||||||
|  |     private CouponApi couponApi; | ||||||
|  |  | ||||||
|  |     @Test | ||||||
|  |     void calculate() { | ||||||
|  |         // 准备参数 | ||||||
|  |         TradePriceCalculateReqBO param = new TradePriceCalculateReqBO() | ||||||
|  |                 .setUserId(233L).setCouponId(1024L) | ||||||
|  |                 .setItems(asList( | ||||||
|  |                         new TradePriceCalculateReqBO.Item().setSkuId(10L).setCount(2).setSelected(true), // 匹配优惠劵 | ||||||
|  |                         new TradePriceCalculateReqBO.Item().setSkuId(20L).setCount(3).setSelected(true), // 匹配优惠劵 | ||||||
|  |                         new TradePriceCalculateReqBO.Item().setSkuId(30L).setCount(4).setSelected(true), // 不匹配优惠劵 | ||||||
|  |                         new TradePriceCalculateReqBO.Item().setSkuId(40L).setCount(5).setSelected(false) // 匹配优惠劵,但是未选中 | ||||||
|  |                     )); | ||||||
|  |         TradePriceCalculateRespBO result = new TradePriceCalculateRespBO() | ||||||
|  |                 .setPrice(new TradePriceCalculateRespBO.Price()) | ||||||
|  |                 .setPromotions(new ArrayList<>()) | ||||||
|  |                 .setItems(asList( | ||||||
|  |                         new TradePriceCalculateRespBO.OrderItem().setSkuId(10L).setCount(2).setSelected(true) | ||||||
|  |                                 .setPrice(100).setSpuId(1L), | ||||||
|  |                         new TradePriceCalculateRespBO.OrderItem().setSkuId(20L).setCount(3).setSelected(true) | ||||||
|  |                                 .setPrice(50).setSpuId(2L), | ||||||
|  |                         new TradePriceCalculateRespBO.OrderItem().setSkuId(30L).setCount(4).setSelected(true) | ||||||
|  |                                 .setPrice(30).setSpuId(3L), | ||||||
|  |                         new TradePriceCalculateRespBO.OrderItem().setSkuId(40L).setCount(5).setSelected(false) | ||||||
|  |                                 .setPrice(60).setSpuId(1L) | ||||||
|  |                 )); | ||||||
|  |         // 保证价格被初始化上 | ||||||
|  |         TradePriceCalculatorHelper.recountPayPrice(result.getItems()); | ||||||
|  |         TradePriceCalculatorHelper.recountAllPrice(result); | ||||||
|  |  | ||||||
|  |         // mock 方法(优惠劵 Coupon 信息) | ||||||
|  |         CouponRespDTO coupon = randomPojo(CouponRespDTO.class, o -> o.setId(1024L).setName("程序员节") | ||||||
|  |                 .setProductScope(PromotionProductScopeEnum.SPU.getScope()).setProductSpuIds(asList(1L, 2L)) | ||||||
|  |                 .setUsePrice(350).setDiscountType(PromotionDiscountTypeEnum.PERCENT.getType()) | ||||||
|  |                 .setDiscountPercent(50).setDiscountLimitPrice(70)); | ||||||
|  |         when(couponApi.validateCoupon(eq(new CouponValidReqDTO().setId(1024L).setUserId(233L)))).thenReturn(coupon); | ||||||
|  |  | ||||||
|  |         // 调用 | ||||||
|  |         tradeCouponPriceCalculator.calculate(param, result); | ||||||
|  |         // 断言 | ||||||
|  |         assertEquals(result.getCouponId(), 1024L); | ||||||
|  |         // 断言:Price 部分 | ||||||
|  |         TradePriceCalculateRespBO.Price price = result.getPrice(); | ||||||
|  |         assertEquals(price.getTotalPrice(), 470); | ||||||
|  |         assertEquals(price.getDiscountPrice(), 0); | ||||||
|  |         assertEquals(price.getPointPrice(), 0); | ||||||
|  |         assertEquals(price.getDeliveryPrice(), 0); | ||||||
|  |         assertEquals(price.getCouponPrice(), 70); | ||||||
|  |         assertEquals(price.getPayPrice(), 400); | ||||||
|  |         // 断言:SKU 1 | ||||||
|  |         TradePriceCalculateRespBO.OrderItem orderItem01 = result.getItems().get(0); | ||||||
|  |         assertEquals(orderItem01.getSkuId(), 10L); | ||||||
|  |         assertEquals(orderItem01.getCount(), 2); | ||||||
|  |         assertEquals(orderItem01.getPrice(), 100); | ||||||
|  |         assertEquals(orderItem01.getDiscountPrice(), 0); | ||||||
|  |         assertEquals(orderItem01.getDeliveryPrice(), 0); | ||||||
|  |         assertEquals(orderItem01.getCouponPrice(), 40); | ||||||
|  |         assertEquals(orderItem01.getPointPrice(), 0); | ||||||
|  |         assertEquals(orderItem01.getPayPrice(), 160); | ||||||
|  |         // 断言:SKU 2 | ||||||
|  |         TradePriceCalculateRespBO.OrderItem orderItem02 = result.getItems().get(1); | ||||||
|  |         assertEquals(orderItem02.getSkuId(), 20L); | ||||||
|  |         assertEquals(orderItem02.getCount(), 3); | ||||||
|  |         assertEquals(orderItem02.getPrice(), 50); | ||||||
|  |         assertEquals(orderItem02.getDiscountPrice(), 0); | ||||||
|  |         assertEquals(orderItem02.getDeliveryPrice(), 0); | ||||||
|  |         assertEquals(orderItem02.getCouponPrice(), 30); | ||||||
|  |         assertEquals(orderItem02.getPointPrice(), 0); | ||||||
|  |         assertEquals(orderItem02.getPayPrice(), 120); | ||||||
|  |         // 断言:SKU 3 | ||||||
|  |         TradePriceCalculateRespBO.OrderItem orderItem03 = result.getItems().get(2); | ||||||
|  |         assertEquals(orderItem03.getSkuId(), 30L); | ||||||
|  |         assertEquals(orderItem03.getCount(), 4); | ||||||
|  |         assertEquals(orderItem03.getPrice(), 30); | ||||||
|  |         assertEquals(orderItem03.getDiscountPrice(), 0); | ||||||
|  |         assertEquals(orderItem03.getCouponPrice(), 0); | ||||||
|  |         assertEquals(orderItem03.getPointPrice(), 0); | ||||||
|  |         assertEquals(orderItem03.getPayPrice(), 120); | ||||||
|  |         // 断言:SKU 4 | ||||||
|  |         TradePriceCalculateRespBO.OrderItem orderItem04 = result.getItems().get(3); | ||||||
|  |         assertEquals(orderItem04.getSkuId(), 40L); | ||||||
|  |         assertEquals(orderItem04.getCount(), 5); | ||||||
|  |         assertEquals(orderItem04.getPrice(), 60); | ||||||
|  |         assertEquals(orderItem04.getDiscountPrice(), 0); | ||||||
|  |         assertEquals(orderItem04.getCouponPrice(), 0); | ||||||
|  |         assertEquals(orderItem04.getPointPrice(), 0); | ||||||
|  |         assertEquals(orderItem04.getPayPrice(), 300); | ||||||
|  |         // 断言 Promotion 部分 | ||||||
|  |         assertEquals(result.getPromotions().size(), 1); | ||||||
|  |         TradePriceCalculateRespBO.Promotion promotion01 = result.getPromotions().get(0); | ||||||
|  |         assertEquals(promotion01.getId(), 1024L); | ||||||
|  |         assertEquals(promotion01.getName(), "程序员节"); | ||||||
|  |         assertEquals(promotion01.getType(), PromotionTypeEnum.COUPON.getType()); | ||||||
|  |         assertEquals(promotion01.getTotalPrice(), 350); | ||||||
|  |         assertEquals(promotion01.getDiscountPrice(), 70); | ||||||
|  |         assertTrue(promotion01.getMatch()); | ||||||
|  |         assertEquals(promotion01.getDescription(), "优惠劵:省 0.70 元"); | ||||||
|  |         assertEquals(promotion01.getItems().size(), 2); | ||||||
|  |         TradePriceCalculateRespBO.PromotionItem promotionItem011 = promotion01.getItems().get(0); | ||||||
|  |         assertEquals(promotionItem011.getSkuId(), 10L); | ||||||
|  |         assertEquals(promotionItem011.getTotalPrice(), 200); | ||||||
|  |         assertEquals(promotionItem011.getDiscountPrice(), 40); | ||||||
|  |         TradePriceCalculateRespBO.PromotionItem promotionItem012 = promotion01.getItems().get(1); | ||||||
|  |         assertEquals(promotionItem012.getSkuId(), 20L); | ||||||
|  |         assertEquals(promotionItem012.getTotalPrice(), 150); | ||||||
|  |         assertEquals(promotionItem012.getDiscountPrice(), 30); | ||||||
|  |     } | ||||||
|  | } | ||||||
		Reference in New Issue
	
	Block a user
	 YunaiV
					YunaiV