mirror of
http://192.168.1.205:9980/cf_devdept2/cf_imes_server.git
synced 2026-08-12 21:02:08 +08:00
产品明细单元测试完善
This commit is contained in:
+1
-15
@@ -1,7 +1,6 @@
|
||||
package com.cf.imes.module.system.controller.admin.funds.products.vo.productDetails;
|
||||
|
||||
import com.cf.imes.framework.common.pojo.PageParam;
|
||||
import com.cf.imes.module.system.validation.products.ProductType;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
@@ -21,22 +20,12 @@ public class ProductDetailsPageReqVO extends PageParam {
|
||||
@Schema(description = "产品ID", example = "1")
|
||||
private Long productId;
|
||||
|
||||
@Schema(description = "购买方式", example = "0")
|
||||
@ProductType
|
||||
private Integer purchaseType;
|
||||
|
||||
@Schema(description = "产品时长", example = "1")
|
||||
private String duration;
|
||||
|
||||
@Schema(description = "正常产量", example = "")
|
||||
private BigDecimal output;
|
||||
private Integer duration;
|
||||
|
||||
@Schema(description = "赠送市场", example = "1")
|
||||
private String giftDuration;
|
||||
|
||||
@Schema(description = "赠送产量", example = "")
|
||||
private BigDecimal giftOutput;
|
||||
|
||||
@Schema(description = "产品原价", example = "100")
|
||||
private BigDecimal originalPrice;
|
||||
|
||||
@@ -46,7 +35,4 @@ public class ProductDetailsPageReqVO extends PageParam {
|
||||
@Schema(description = "产品现价", example = "80")
|
||||
private BigDecimal currentPrice;
|
||||
|
||||
@Schema(description = "是否特惠", example = "0")
|
||||
private Boolean isDiscounted;
|
||||
|
||||
}
|
||||
|
||||
+6
-8
@@ -6,6 +6,7 @@ import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.DecimalMax;
|
||||
import jakarta.validation.constraints.DecimalMin;
|
||||
import jakarta.validation.constraints.Digits;
|
||||
import jakarta.validation.constraints.Min;
|
||||
import lombok.Data;
|
||||
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
@@ -25,19 +26,16 @@ public class ProductDetailsSaveReqVO {
|
||||
@Schema(description = "购买方式", requiredMode = Schema.RequiredMode.REQUIRED, example = "0")
|
||||
private Integer purchaseType = ProductsPurchaseTypeEnum.DURATION.getStatus();
|
||||
|
||||
@Schema(description = "产品时间,格式:时长值", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
private String duration;
|
||||
@Schema(description = "产品时长,格式:时长值", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
@Min(value = 1, message = "产品时长必须大于0")
|
||||
@NotNull(message = "产品时长不能为空")
|
||||
private Integer duration;
|
||||
|
||||
@Schema(description = "产品时长单位,0:年", example = "1")
|
||||
@ProductDurationUnitValid
|
||||
@NotNull(message = "产品时长单位不能为空")
|
||||
private Integer durationUnit;
|
||||
|
||||
@Schema(description = "产品产量", requiredMode = Schema.RequiredMode.REQUIRED, example = "")
|
||||
private BigDecimal output;
|
||||
|
||||
@Schema(description = "赠送产量", requiredMode = Schema.RequiredMode.REQUIRED, example = "")
|
||||
private BigDecimal giftOutput;
|
||||
|
||||
@Schema(description = "折扣", requiredMode = Schema.RequiredMode.REQUIRED, example = "0.8")
|
||||
@DecimalMax(value = "100", message = "折扣必须小于等于100")
|
||||
@DecimalMin(value = "0", message = "折扣必须大于等于0")
|
||||
|
||||
-21
@@ -35,11 +35,6 @@ public class ProductsDetailDO extends BaseDO {
|
||||
*/
|
||||
private Long productId;
|
||||
|
||||
/**
|
||||
* 产品明细购买方式 0时长 1产量
|
||||
*/
|
||||
private Integer purchaseType;
|
||||
|
||||
/**
|
||||
* 正常时间,不加赠送时间
|
||||
*/
|
||||
@@ -50,24 +45,8 @@ public class ProductsDetailDO extends BaseDO {
|
||||
*/
|
||||
private Integer durationUnit;
|
||||
|
||||
/**
|
||||
* 正常产量,不加赠送产量
|
||||
*/
|
||||
@TableField("`output`")
|
||||
private BigDecimal output;
|
||||
|
||||
/**
|
||||
* 赠送产量
|
||||
*/
|
||||
private BigDecimal giftOutput;
|
||||
|
||||
/**
|
||||
* 折扣
|
||||
*/
|
||||
private BigDecimal discount;
|
||||
|
||||
/**
|
||||
* 是否特惠: 0否1是
|
||||
*/
|
||||
private Boolean isDiscounted;
|
||||
}
|
||||
|
||||
+16
-21
@@ -7,8 +7,6 @@ import com.cf.imes.module.system.controller.admin.funds.products.vo.productDetai
|
||||
import com.cf.imes.module.system.dal.dataobject.funds.products.ProductsDetailDO;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* 产品明细表 product_details Mapper
|
||||
*
|
||||
@@ -17,23 +15,32 @@ import java.math.BigDecimal;
|
||||
@Mapper
|
||||
public interface ProductsDetailMapper extends BaseMapperX<ProductsDetailDO> {
|
||||
|
||||
/**
|
||||
* 分页查询
|
||||
*
|
||||
* @param reqVO
|
||||
* @return
|
||||
*/
|
||||
default PageResult<ProductsDetailDO> selectPage(ProductDetailsPageReqVO reqVO) {
|
||||
return selectPage(reqVO, new LambdaQueryWrapperX<ProductsDetailDO>()
|
||||
.eqIfPresent(ProductsDetailDO::getPurchaseType, reqVO.getPurchaseType())
|
||||
.eqIfPresent(ProductsDetailDO::getProductId, reqVO.getProductId())
|
||||
.eqIfPresent(ProductsDetailDO::getDuration, reqVO.getDuration())
|
||||
.eqIfPresent(ProductsDetailDO::getOutput, reqVO.getOutput())
|
||||
.eqIfPresent(ProductsDetailDO::getGiftOutput, reqVO.getGiftOutput())
|
||||
.eqIfPresent(ProductsDetailDO::getDiscount, reqVO.getDiscount())
|
||||
.eqIfPresent(ProductsDetailDO::getIsDiscounted, reqVO.getIsDiscounted())
|
||||
.eqIfPresent(ProductsDetailDO::getDeleted, false)
|
||||
.orderByAsc(ProductsDetailDO::getDuration)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
// 时长查重,添加productId为查询条件
|
||||
default int selectCountByDuration(Long productId, Long productDetailId, String duration, Integer durationUnit) {
|
||||
/**
|
||||
* 查询产品id下相同时长、时长单位的数量
|
||||
*
|
||||
* @param productId
|
||||
* @param productDetailId
|
||||
* @param duration
|
||||
* @param durationUnit
|
||||
* @return
|
||||
*/
|
||||
default int selectCountByDuration(Long productId, Long productDetailId, Integer duration, Integer durationUnit) {
|
||||
LambdaQueryWrapperX<ProductsDetailDO> queryWrapper = new LambdaQueryWrapperX<>();
|
||||
queryWrapper.eq(ProductsDetailDO::getProductId, productId)
|
||||
.eq(ProductsDetailDO::getDeleted, false)
|
||||
@@ -42,16 +49,4 @@ public interface ProductsDetailMapper extends BaseMapperX<ProductsDetailDO> {
|
||||
.neIfPresent(ProductsDetailDO::getId, productDetailId);
|
||||
return Math.toIntExact(selectCount(queryWrapper));
|
||||
}
|
||||
|
||||
|
||||
|
||||
// 产量查重
|
||||
default int selectCountByOutput(BigDecimal output, Long productId) {
|
||||
LambdaQueryWrapperX<ProductsDetailDO> queryWrapper = new LambdaQueryWrapperX<>();
|
||||
queryWrapper.eq(ProductsDetailDO::getProductId, productId)
|
||||
.eq(ProductsDetailDO::getDeleted, false)
|
||||
.eq(ProductsDetailDO::getDuration, output);
|
||||
return Math.toIntExact(selectCount(queryWrapper));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
+1
-50
@@ -16,7 +16,6 @@ import com.cf.imes.module.system.dal.mysql.funds.products.ProductsDetailMapper;
|
||||
import com.cf.imes.module.system.dal.mysql.funds.products.ProductsMapper;
|
||||
import com.cf.imes.module.system.enums.pay.ProductDurationUnitEnum;
|
||||
import com.cf.imes.module.system.enums.products.ProductStatusEnum;
|
||||
import com.cf.imes.module.system.enums.products.ProductsPurchaseTypeEnum;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
@@ -48,18 +47,9 @@ public class ProductsDetailServiceImpl implements ProductsDetailService {
|
||||
// 校验是否有这个产品
|
||||
validateProductExistAndNotOnList(createReqVO.getProductId());
|
||||
|
||||
if (ProductsPurchaseTypeEnum.DURATION.getStatus().equals(createReqVO.getPurchaseType())) {
|
||||
// 校验时长
|
||||
checkDuration(createReqVO.getDuration(), createReqVO.getDurationUnit());
|
||||
|
||||
// 查询是否有重复的定价
|
||||
checkProductDetails(createReqVO);
|
||||
|
||||
} else if (createReqVO.getPurchaseType().equals(ProductsPurchaseTypeEnum.OUTPUT.getStatus())) {
|
||||
// todo 暂不支持产量
|
||||
throw exception(PRODUCTS_OUTPUT_NOT_SUPPORT);
|
||||
}
|
||||
|
||||
ProductsDetailDO productDetailsDO = BeanUtils.toBean(createReqVO, ProductsDetailDO.class);
|
||||
productDetailsMapper.insert(productDetailsDO);
|
||||
return productDetailsDO.getId();
|
||||
@@ -73,17 +63,9 @@ public class ProductsDetailServiceImpl implements ProductsDetailService {
|
||||
|
||||
validateProductDetailsExists(updateReqVO.getId());
|
||||
|
||||
if (updateReqVO.getPurchaseType().equals(ProductsPurchaseTypeEnum.DURATION.getStatus())) {
|
||||
// 校验时长
|
||||
checkDuration(updateReqVO.getDuration(), updateReqVO.getDurationUnit());
|
||||
// 校验同时长是否还有其他的定价规则
|
||||
checkProductDetails(updateReqVO);
|
||||
|
||||
} else if (updateReqVO.getPurchaseType().equals(ProductsPurchaseTypeEnum.OUTPUT.getStatus())) {
|
||||
// todo 暂不支持产量
|
||||
throw exception(PRODUCTS_OUTPUT_NOT_SUPPORT);
|
||||
}
|
||||
|
||||
productDetailsMapper.update(new LambdaUpdateWrapper<ProductsDetailDO>()
|
||||
.eq(ProductsDetailDO::getId, updateReqVO.getId())
|
||||
.set(ProductsDetailDO::getDiscount, updateReqVO.getDiscount())
|
||||
@@ -132,29 +114,6 @@ public class ProductsDetailServiceImpl implements ProductsDetailService {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 校验时长
|
||||
*
|
||||
* @param duration
|
||||
* @param timeUnit
|
||||
* @return
|
||||
*/
|
||||
private void checkDuration(String duration, Integer timeUnit) {
|
||||
AssertUtils.notEmpty(duration, PRODUCTS_DURATION_NOT_NULL);
|
||||
AssertUtils.notEmpty(timeUnit, PRODUCTS_DURATION_NOT_NULL);
|
||||
|
||||
// 校验时长值
|
||||
if (!duration.matches("^\\d+$")) {
|
||||
throw exception(PRODUCTS_DURATION_INT_ERR);
|
||||
}
|
||||
|
||||
int timeValue = Integer.parseInt(duration);
|
||||
if (timeValue <= 0) {
|
||||
throw exception(PRODUCTS_DURATION_INT_ERR);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 产品是否存在
|
||||
*
|
||||
@@ -203,21 +162,13 @@ public class ProductsDetailServiceImpl implements ProductsDetailService {
|
||||
*/
|
||||
private void checkProductDetails(ProductDetailsSaveReqVO createReqVO) {
|
||||
int count;
|
||||
if (createReqVO.getPurchaseType() == 0) {
|
||||
String duration = createReqVO.getDuration();
|
||||
Integer duration = createReqVO.getDuration();
|
||||
Integer durationUnit = createReqVO.getDurationUnit();
|
||||
// 时长去重
|
||||
count = productDetailsMapper.selectCountByDuration(createReqVO.getProductId(), createReqVO.getId(), duration, durationUnit);
|
||||
if (count > 0) {
|
||||
throw ServiceExceptionUtil.exception(PRODUCTS_DETAIL_DURATION_EXIST, duration, ProductDurationUnitEnum.getDesc(durationUnit));
|
||||
}
|
||||
} else if (createReqVO.getPurchaseType() == 1) {
|
||||
//产量去重
|
||||
count = productDetailsMapper.selectCountByOutput(createReqVO.getOutput(), createReqVO.getProductId());
|
||||
if (count > 0) {
|
||||
throw exception(PRODUCTS_DETAIL_OUTPUT_EXIST);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+294
@@ -0,0 +1,294 @@
|
||||
package com.cf.imes.module.system.service.funds.products;
|
||||
|
||||
import com.cf.imes.framework.common.pojo.PageResult;
|
||||
import com.cf.imes.framework.test.core.ut.BaseDbAndRedisUnitTest;
|
||||
import com.cf.imes.module.system.controller.admin.funds.products.vo.productDetails.ProductDetailsPageReqVO;
|
||||
import com.cf.imes.module.system.controller.admin.funds.products.vo.productDetails.ProductDetailsSaveReqVO;
|
||||
import com.cf.imes.module.system.dal.dataobject.funds.products.ProductsDO;
|
||||
import com.cf.imes.module.system.dal.dataobject.funds.products.ProductsDetailDO;
|
||||
import com.cf.imes.module.system.dal.mysql.funds.products.ProductsDetailMapper;
|
||||
import com.cf.imes.module.system.dal.mysql.funds.products.ProductsMapper;
|
||||
import com.cf.imes.module.system.enums.pay.ProductDurationUnitEnum;
|
||||
import com.cf.imes.module.system.enums.products.ProductStatusEnum;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.test.context.bean.override.mockito.MockitoBean;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
import static com.cf.imes.framework.common.util.object.ObjectUtils.cloneIgnoreId;
|
||||
import static com.cf.imes.framework.test.core.util.AssertUtils.assertPojoEquals;
|
||||
import static com.cf.imes.framework.test.core.util.AssertUtils.assertServiceException;
|
||||
import static com.cf.imes.framework.test.core.util.RandomUtils.randomPojo;
|
||||
import static com.cf.imes.module.system.enums.ErrorCodeConstants.PRODUCTS_DETAIL_DURATION_EXIST;
|
||||
import static com.cf.imes.module.system.enums.ErrorCodeConstants.PRODUCTS_DETAIL_NO_EXIST;
|
||||
import static com.cf.imes.module.system.enums.ErrorCodeConstants.PRODUCTS_DETAIL_NO_UPDATE;
|
||||
import static com.cf.imes.module.system.enums.ErrorCodeConstants.PRODUCTS_NOT_NOLIST;
|
||||
import static com.cf.imes.module.system.enums.ErrorCodeConstants.PRODUCTS_NO_EXIST;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
/**
|
||||
* @author Gqr
|
||||
* @since 2025/10/14 13:48
|
||||
*/
|
||||
@Import(ProductsDetailServiceImpl.class)
|
||||
public class ProductsDetailServiceImplTest extends BaseDbAndRedisUnitTest {
|
||||
@Resource
|
||||
private ProductsDetailServiceImpl productsDetailService;
|
||||
|
||||
@Resource
|
||||
private ProductsDetailMapper productsDetailMapper;
|
||||
|
||||
@MockitoBean
|
||||
private ProductsMapper productsMapper;
|
||||
|
||||
@Test
|
||||
void testCreateProductDetails() {
|
||||
// mock下架状态的产品
|
||||
ProductsDO mockProduct = new ProductsDO();
|
||||
mockProduct.setId(123L);
|
||||
mockProduct.setDeleted(false);
|
||||
mockProduct.setStatus(ProductStatusEnum.PRODUCT_DELIS.getStatus());
|
||||
|
||||
when(productsMapper.selectOne(any())).thenReturn(mockProduct);
|
||||
|
||||
ProductDetailsSaveReqVO productDetailsSaveReqVO = randomPojo(ProductDetailsSaveReqVO.class, p -> {
|
||||
p.setId(null);
|
||||
});
|
||||
|
||||
// 调用
|
||||
Long id = productsDetailService.create(productDetailsSaveReqVO);
|
||||
// 断言
|
||||
assertNotNull(id);
|
||||
// 校验记录的属性是否正确
|
||||
ProductsDetailDO productsDetailDO = productsDetailMapper.selectById(id);
|
||||
assertPojoEquals(productDetailsSaveReqVO, productsDetailDO, "id");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCreateProductDetails_ProductNotExist() {
|
||||
ProductDetailsSaveReqVO productDetailsSaveReqVO = randomPojo(ProductDetailsSaveReqVO.class);
|
||||
when(productsMapper.selectOne(any())).thenReturn(null);
|
||||
|
||||
assertServiceException(() -> productsDetailService.create(productDetailsSaveReqVO),
|
||||
PRODUCTS_NO_EXIST);
|
||||
|
||||
ProductsDO mockProduct = new ProductsDO();
|
||||
mockProduct.setStatus(ProductStatusEnum.PRODUCT_UPDATES.getStatus());
|
||||
when(productsMapper.selectOne(any())).thenReturn(mockProduct);
|
||||
|
||||
assertServiceException(() -> productsDetailService.create(productDetailsSaveReqVO),
|
||||
PRODUCTS_DETAIL_NO_UPDATE);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCheckProductDetails_duplicate() {
|
||||
// mock下架状态的产品
|
||||
ProductsDO mockProduct = new ProductsDO();
|
||||
mockProduct.setId(123L);
|
||||
mockProduct.setDeleted(false);
|
||||
mockProduct.setStatus(ProductStatusEnum.PRODUCT_DELIS.getStatus());
|
||||
|
||||
when(productsMapper.selectOne(any())).thenReturn(mockProduct);
|
||||
// 插入一条与 createReqVO 冲突的数据
|
||||
ProductsDetailDO existing = new ProductsDetailDO();
|
||||
existing.setProductId(1L);
|
||||
existing.setDuration(12);
|
||||
existing.setDurationUnit(0);
|
||||
existing.setDeleted(false);
|
||||
productsDetailMapper.insert(existing);
|
||||
|
||||
// 模拟新增同样 duration + unit 的记录
|
||||
ProductDetailsSaveReqVO reqVO = new ProductDetailsSaveReqVO()
|
||||
.setProductId(existing.getProductId())
|
||||
.setDuration(existing.getDuration())
|
||||
.setDurationUnit(existing.getDurationUnit());
|
||||
|
||||
assertServiceException(() -> productsDetailService.create(reqVO),
|
||||
PRODUCTS_DETAIL_DURATION_EXIST, reqVO.getDuration(), ProductDurationUnitEnum.getDesc(reqVO.getDurationUnit()));
|
||||
}
|
||||
|
||||
@Test
|
||||
void updateProductDetails() {
|
||||
// mock下架状态的产品
|
||||
ProductsDO mockProduct = new ProductsDO();
|
||||
mockProduct.setId(123L);
|
||||
mockProduct.setDeleted(false);
|
||||
mockProduct.setStatus(ProductStatusEnum.PRODUCT_DELIS.getStatus());
|
||||
|
||||
when(productsMapper.selectOne(any())).thenReturn(mockProduct);
|
||||
|
||||
ProductsDetailDO detail = new ProductsDetailDO();
|
||||
detail.setProductId(mockProduct.getId());
|
||||
detail.setDuration(12);
|
||||
detail.setDurationUnit(1);
|
||||
detail.setDeleted(false);
|
||||
productsDetailMapper.insert(detail);
|
||||
|
||||
// 构造请求
|
||||
ProductDetailsSaveReqVO reqVO = new ProductDetailsSaveReqVO()
|
||||
.setId(detail.getId())
|
||||
.setProductId(mockProduct.getId())
|
||||
.setDuration(6)
|
||||
.setDurationUnit(0);
|
||||
|
||||
// 调用
|
||||
productsDetailService.update(reqVO);
|
||||
|
||||
// 验证结果
|
||||
ProductsDetailDO updated = productsDetailMapper.selectById(detail.getId());
|
||||
assertEquals(6, updated.getDuration());
|
||||
}
|
||||
|
||||
@Test
|
||||
void deleteTest(){
|
||||
// mock下架状态的产品
|
||||
ProductsDO mockProduct = new ProductsDO();
|
||||
mockProduct.setId(123L);
|
||||
mockProduct.setDeleted(false);
|
||||
mockProduct.setStatus(ProductStatusEnum.PRODUCT_DELIS.getStatus());
|
||||
|
||||
when(productsMapper.selectOne(any())).thenReturn(mockProduct);
|
||||
|
||||
ProductsDetailDO detail = new ProductsDetailDO();
|
||||
detail.setProductId(mockProduct.getId());
|
||||
detail.setDuration(12);
|
||||
detail.setDurationUnit(1);
|
||||
detail.setDeleted(false);
|
||||
productsDetailMapper.insert(detail);
|
||||
|
||||
// 调用删除
|
||||
productsDetailService.delete(detail.getId());
|
||||
|
||||
// 验证确实被删
|
||||
assertNull(productsDetailMapper.selectById(detail.getId()));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGet_success() {
|
||||
// 插入一条数据
|
||||
ProductsDetailDO detail = new ProductsDetailDO();
|
||||
detail.setId(321L);
|
||||
detail.setDeleted(false);
|
||||
detail.setProductId(123L);
|
||||
productsDetailMapper.insert(detail);
|
||||
|
||||
ProductsDetailDO result = productsDetailService.get(detail.getId());
|
||||
assertNotNull(result);
|
||||
assertEquals(321L, result.getId());
|
||||
assertEquals(123L, result.getProductId());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetPage_success() {
|
||||
ProductsDetailDO detail = randomPojo(ProductsDetailDO.class, o -> {
|
||||
o.setProductId(123L);
|
||||
o.setDuration(1);
|
||||
o.setDurationUnit(ProductDurationUnitEnum.YEAR.getCode());
|
||||
o.setDiscount(BigDecimal.valueOf(100));
|
||||
o.setDeleted(false);
|
||||
});
|
||||
|
||||
productsDetailMapper.insert(detail);
|
||||
|
||||
// 不匹配 productId
|
||||
productsDetailMapper.insert(cloneIgnoreId(detail, o -> o.setProductId(321L)));
|
||||
|
||||
// 不匹配 duration
|
||||
productsDetailMapper.insert(cloneIgnoreId(detail, o -> o.setDuration(2)));
|
||||
|
||||
// 不匹配 discount
|
||||
productsDetailMapper.insert(cloneIgnoreId(detail, o -> o.setDiscount(BigDecimal.valueOf(99))));
|
||||
|
||||
// 被逻辑删除
|
||||
productsDetailMapper.insert(cloneIgnoreId(detail, o -> o.setDeleted(true)));
|
||||
|
||||
// ============ 构造查询参数 ============
|
||||
ProductDetailsPageReqVO reqVO = new ProductDetailsPageReqVO();
|
||||
reqVO.setProductId(123L);
|
||||
reqVO.setDuration(1);
|
||||
reqVO.setDiscount(BigDecimal.valueOf(100));
|
||||
reqVO.setPageNo(1);
|
||||
reqVO.setPageSize(10);
|
||||
|
||||
// ============ 调用方法 ============
|
||||
PageResult<ProductsDetailDO> pageResult = productsDetailService.getPage(reqVO);
|
||||
|
||||
// ============ 断言结果 ============
|
||||
assertEquals(1, pageResult.getTotal(), "分页结果数量应为1");
|
||||
assertEquals(1, pageResult.getList().size(), "分页列表长度应为1");
|
||||
assertPojoEquals(detail, pageResult.getList().get(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
void validateProductDetailsExists_idNull(){
|
||||
assertServiceException(() -> productsDetailService.validateProductDetailsExists(null), PRODUCTS_DETAIL_NO_EXIST);
|
||||
}
|
||||
|
||||
@Test
|
||||
void validateProductDetailsExists_notExist(){
|
||||
assertServiceException(() -> productsDetailService.validateProductDetailsExists(1234567L), PRODUCTS_DETAIL_NO_EXIST);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
void testValidateProductExist_success() {
|
||||
// 模拟返回一个正常的产品
|
||||
ProductsDO product = new ProductsDO();
|
||||
product.setId(1L);
|
||||
product.setDeleted(false);
|
||||
product.setStatus(ProductStatusEnum.PRODUCT_UPDATES.getStatus());
|
||||
|
||||
when(productsMapper.selectOne(any())).thenReturn(product);
|
||||
|
||||
ProductsDO result = productsDetailService.validateProductExist(1L);
|
||||
|
||||
assertNotNull(result);
|
||||
assertEquals(1L, result.getId());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testValidateProductExist_notExist() {
|
||||
// 模拟数据库返回 null
|
||||
when(productsMapper.selectOne(any())).thenReturn(null);
|
||||
|
||||
assertServiceException(() -> productsDetailService.validateProductExist(1L), PRODUCTS_NO_EXIST);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testValidateProductExist_statusNotUp() {
|
||||
ProductsDO product = new ProductsDO();
|
||||
product.setId(1L);
|
||||
product.setDeleted(false);
|
||||
product.setStatus(ProductStatusEnum.PRODUCT_DELIS.getStatus()); // 非 PRODUCT_UPDATES 状态
|
||||
|
||||
when(productsMapper.selectOne(any())).thenReturn(product);
|
||||
|
||||
assertServiceException(() -> productsDetailService.validateProductExist(1L), PRODUCTS_NOT_NOLIST);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetProductDetailOneYearDiscount_exists() {
|
||||
// 模拟数据库返回一年期明细
|
||||
ProductsDetailDO detailDO = new ProductsDetailDO();
|
||||
detailDO.setProductId(1L);
|
||||
detailDO.setDuration(1);
|
||||
detailDO.setDurationUnit(ProductDurationUnitEnum.YEAR.getCode());
|
||||
detailDO.setDiscount(BigDecimal.valueOf(85));
|
||||
productsDetailMapper.insert(detailDO);
|
||||
|
||||
BigDecimal discount = productsDetailService.getProductDetailOneYearDiscount(1L);
|
||||
assertEquals(BigDecimal.valueOf(85), discount);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetProductDetailOneYearDiscount_notExist() {
|
||||
BigDecimal discount = productsDetailService.getProductDetailOneYearDiscount(123L);
|
||||
assertEquals(BigDecimal.valueOf(100), discount);
|
||||
}
|
||||
}
|
||||
@@ -693,9 +693,23 @@ CREATE TABLE IF NOT EXISTS "products" (
|
||||
"price" decimal(8,2),
|
||||
"description" varchar,
|
||||
"creator" varchar DEFAULT '',
|
||||
"create_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updater" varchar DEFAULT '',
|
||||
"update_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"deleted" bit NOT NULL DEFAULT FALSE,
|
||||
PRIMARY KEY ("id")
|
||||
) COMMENT '产品表';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS "products_details" (
|
||||
"id" BIGINT NOT NULL GENERATED BY DEFAULT AS IDENTITY,
|
||||
"product_id" BIGINT NOT NULL,
|
||||
"duration" VARCHAR,
|
||||
"duration_unit" TINYINT,
|
||||
"discount" DECIMAL(3),
|
||||
"creator" VARCHAR DEFAULT '',
|
||||
"create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updater" varchar(64) DEFAULT '',
|
||||
"update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"deleted" bit NOT NULL DEFAULT FALSE,
|
||||
PRIMARY KEY ("id")
|
||||
) COMMENT '产品购买信息表 products_details';
|
||||
|
||||
Reference in New Issue
Block a user