mirror of
https://gitee.com/huangge1199_admin/vue-pro.git
synced 2024-11-22 23:31:52 +08:00
feature(单元测试): ProductSpuServiceImpl单元测试
This commit is contained in:
parent
31f5b27d01
commit
aea763e96e
@ -248,7 +248,7 @@ DROP TABLE IF EXISTS `product_spu`;
|
|||||||
CREATE TABLE `product_spu` (
|
CREATE TABLE `product_spu` (
|
||||||
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键',
|
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键',
|
||||||
`tenant_id` bigint NOT NULL DEFAULT '0' COMMENT '租户编号',
|
`tenant_id` bigint NOT NULL DEFAULT '0' COMMENT '租户编号',
|
||||||
`brand_id` int DEFAULT NULL COMMENT '商品品牌编号',
|
`brand_id` bigint DEFAULT NULL COMMENT '商品品牌编号',
|
||||||
`category_id` bigint NOT NULL COMMENT '分类id',
|
`category_id` bigint NOT NULL COMMENT '分类id',
|
||||||
`spec_type` int NOT NULL COMMENT '规格类型:0 单规格 1 多规格',
|
`spec_type` int NOT NULL COMMENT '规格类型:0 单规格 1 多规格',
|
||||||
`code` varchar(128) DEFAULT NULL COMMENT '商品编码',
|
`code` varchar(128) DEFAULT NULL COMMENT '商品编码',
|
||||||
|
@ -19,12 +19,12 @@ public enum ProductSpuStatusEnum implements IntArrayValuable {
|
|||||||
DISABLE(0, "下架"),
|
DISABLE(0, "下架"),
|
||||||
ENABLE(1, "上架"),;
|
ENABLE(1, "上架"),;
|
||||||
|
|
||||||
public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(ProductSpuStatusEnum::getStyle).toArray();
|
public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(ProductSpuStatusEnum::getStatus).toArray();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 状态
|
* 状态
|
||||||
*/
|
*/
|
||||||
private final Integer style;
|
private final Integer status;
|
||||||
/**
|
/**
|
||||||
* 状态名
|
* 状态名
|
||||||
*/
|
*/
|
||||||
|
@ -97,6 +97,7 @@ public class ProductSkuDO extends BaseDO {
|
|||||||
* 商品属性
|
* 商品属性
|
||||||
*/
|
*/
|
||||||
@Data
|
@Data
|
||||||
|
@AllArgsConstructor
|
||||||
public static class Property {
|
public static class Property {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -28,7 +28,10 @@ import org.springframework.transaction.annotation.Transactional;
|
|||||||
import org.springframework.validation.annotation.Validated;
|
import org.springframework.validation.annotation.Validated;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import java.util.*;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||||
@ -44,7 +47,7 @@ import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SPU_NOT_E
|
|||||||
public class ProductSpuServiceImpl implements ProductSpuService {
|
public class ProductSpuServiceImpl implements ProductSpuService {
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
private ProductSpuMapper ProductSpuMapper;
|
private ProductSpuMapper productSpuMapper;
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
private ProductCategoryService categoryService;
|
private ProductCategoryService categoryService;
|
||||||
@ -77,7 +80,7 @@ public class ProductSpuServiceImpl implements ProductSpuService {
|
|||||||
spu.setMaxPrice(CollectionUtils.getMaxValue(skuCreateReqList, ProductSkuCreateOrUpdateReqVO::getPrice));
|
spu.setMaxPrice(CollectionUtils.getMaxValue(skuCreateReqList, ProductSkuCreateOrUpdateReqVO::getPrice));
|
||||||
spu.setMinPrice(CollectionUtils.getMinValue(skuCreateReqList, ProductSkuCreateOrUpdateReqVO::getPrice));
|
spu.setMinPrice(CollectionUtils.getMinValue(skuCreateReqList, ProductSkuCreateOrUpdateReqVO::getPrice));
|
||||||
spu.setTotalStock(CollectionUtils.getSumValue(skuCreateReqList, ProductSkuCreateOrUpdateReqVO::getStock, Integer::sum));
|
spu.setTotalStock(CollectionUtils.getSumValue(skuCreateReqList, ProductSkuCreateOrUpdateReqVO::getStock, Integer::sum));
|
||||||
ProductSpuMapper.insert(spu);
|
productSpuMapper.insert(spu);
|
||||||
// 插入 SKU
|
// 插入 SKU
|
||||||
productSkuService.createSkus(spu.getId(), skuCreateReqList);
|
productSkuService.createSkus(spu.getId(), skuCreateReqList);
|
||||||
// 返回
|
// 返回
|
||||||
@ -95,7 +98,6 @@ public class ProductSpuServiceImpl implements ProductSpuService {
|
|||||||
brandService.validateProductBrand(updateReqVO.getBrandId());
|
brandService.validateProductBrand(updateReqVO.getBrandId());
|
||||||
// 校验SKU
|
// 校验SKU
|
||||||
List<ProductSkuCreateOrUpdateReqVO> skuCreateReqList = updateReqVO.getSkus();
|
List<ProductSkuCreateOrUpdateReqVO> skuCreateReqList = updateReqVO.getSkus();
|
||||||
// 多规格才需校验
|
|
||||||
productSkuService.validateSkus(skuCreateReqList, updateReqVO.getSpecType());
|
productSkuService.validateSkus(skuCreateReqList, updateReqVO.getSpecType());
|
||||||
|
|
||||||
// 更新 SPU
|
// 更新 SPU
|
||||||
@ -104,7 +106,7 @@ public class ProductSpuServiceImpl implements ProductSpuService {
|
|||||||
updateObj.setMaxPrice(CollectionUtils.getMaxValue(skuCreateReqList, ProductSkuCreateOrUpdateReqVO::getPrice));
|
updateObj.setMaxPrice(CollectionUtils.getMaxValue(skuCreateReqList, ProductSkuCreateOrUpdateReqVO::getPrice));
|
||||||
updateObj.setMinPrice(CollectionUtils.getMinValue(skuCreateReqList, ProductSkuCreateOrUpdateReqVO::getPrice));
|
updateObj.setMinPrice(CollectionUtils.getMinValue(skuCreateReqList, ProductSkuCreateOrUpdateReqVO::getPrice));
|
||||||
updateObj.setTotalStock(CollectionUtils.getSumValue(skuCreateReqList, ProductSkuCreateOrUpdateReqVO::getStock, Integer::sum));
|
updateObj.setTotalStock(CollectionUtils.getSumValue(skuCreateReqList, ProductSkuCreateOrUpdateReqVO::getStock, Integer::sum));
|
||||||
ProductSpuMapper.updateById(updateObj);
|
productSpuMapper.updateById(updateObj);
|
||||||
// 批量更新 SKU
|
// 批量更新 SKU
|
||||||
productSkuService.updateProductSkus(updateObj.getId(), updateReqVO.getSkus());
|
productSkuService.updateProductSkus(updateObj.getId(), updateReqVO.getSkus());
|
||||||
}
|
}
|
||||||
@ -115,13 +117,13 @@ public class ProductSpuServiceImpl implements ProductSpuService {
|
|||||||
// 校验存在
|
// 校验存在
|
||||||
validateSpuExists(id);
|
validateSpuExists(id);
|
||||||
// 删除 SPU
|
// 删除 SPU
|
||||||
ProductSpuMapper.deleteById(id);
|
productSpuMapper.deleteById(id);
|
||||||
// 删除关联的 SKU
|
// 删除关联的 SKU
|
||||||
productSkuService.deleteSkuBySpuId(id);
|
productSkuService.deleteSkuBySpuId(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void validateSpuExists(Long id) {
|
private void validateSpuExists(Long id) {
|
||||||
if (ProductSpuMapper.selectById(id) == null) {
|
if (productSpuMapper.selectById(id) == null) {
|
||||||
throw exception(SPU_NOT_EXISTS);
|
throw exception(SPU_NOT_EXISTS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -129,7 +131,7 @@ public class ProductSpuServiceImpl implements ProductSpuService {
|
|||||||
@Override
|
@Override
|
||||||
// TODO @芋艿:需要再 review 下
|
// TODO @芋艿:需要再 review 下
|
||||||
public ProductSpuDetailRespVO getSpuDetail(Long id) {
|
public ProductSpuDetailRespVO getSpuDetail(Long id) {
|
||||||
ProductSpuDO spu = ProductSpuMapper.selectById(id);
|
ProductSpuDO spu = productSpuMapper.selectById(id);
|
||||||
ProductSpuDetailRespVO respVO = BeanUtil.copyProperties(spu, ProductSpuDetailRespVO.class);
|
ProductSpuDetailRespVO respVO = BeanUtil.copyProperties(spu, ProductSpuDetailRespVO.class);
|
||||||
if (null != spu) {
|
if (null != spu) {
|
||||||
List<ProductSpuDetailRespVO.Sku> skuReqs = ProductSkuConvert.INSTANCE.convertList03(productSkuService.getSkusBySpuId(id));
|
List<ProductSpuDetailRespVO.Sku> skuReqs = ProductSkuConvert.INSTANCE.convertList03(productSkuService.getSkusBySpuId(id));
|
||||||
@ -162,19 +164,6 @@ public class ProductSpuServiceImpl implements ProductSpuService {
|
|||||||
});
|
});
|
||||||
respVO.setProductPropertyViews(productPropertyViews);
|
respVO.setProductPropertyViews(productPropertyViews);
|
||||||
}
|
}
|
||||||
// 组合分类
|
|
||||||
// if (null != respVO.getCategoryId()) {
|
|
||||||
// LinkedList<Long> categoryArray = new LinkedList<>();
|
|
||||||
// Long parentId = respVO.getCategoryId();
|
|
||||||
// categoryArray.addFirst(parentId);
|
|
||||||
// while (parentId != 0) {
|
|
||||||
// parentId = categoryService.getCategory(parentId).getParentId();
|
|
||||||
// if (parentId > 0) {
|
|
||||||
// categoryArray.addFirst(parentId);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// }
|
|
||||||
respVO.setCategoryIds(respVO.getCategoryId());
|
respVO.setCategoryIds(respVO.getCategoryId());
|
||||||
}
|
}
|
||||||
return respVO;
|
return respVO;
|
||||||
@ -182,12 +171,12 @@ public class ProductSpuServiceImpl implements ProductSpuService {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ProductSpuRespVO getSpu(Long id) {
|
public ProductSpuRespVO getSpu(Long id) {
|
||||||
return ProductSpuConvert.INSTANCE.convert(ProductSpuMapper.selectById(id));
|
return ProductSpuConvert.INSTANCE.convert(productSpuMapper.selectById(id));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<ProductSpuDO> getSpuList(Collection<Long> ids) {
|
public List<ProductSpuDO> getSpuList(Collection<Long> ids) {
|
||||||
return ProductSpuMapper.selectBatchIds(ids);
|
return productSpuMapper.selectBatchIds(ids);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -199,13 +188,14 @@ public class ProductSpuServiceImpl implements ProductSpuService {
|
|||||||
remindSpuIds.add(null);
|
remindSpuIds.add(null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ProductSpuConvert.INSTANCE.convertPage(ProductSpuMapper.selectPage(pageReqVO, remindSpuIds));
|
return ProductSpuConvert.INSTANCE.convertPage(productSpuMapper.selectPage(pageReqVO, remindSpuIds));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PageResult<AppSpuPageRespVO> getSpuPage(AppSpuPageReqVO pageReqVO) {
|
public PageResult<AppSpuPageRespVO> getSpuPage(AppSpuPageReqVO pageReqVO) {
|
||||||
PageResult<ProductSpuDO> productSpuDOPageResult = ProductSpuMapper.selectPage(ProductSpuConvert.INSTANCE.convert(pageReqVO));
|
PageResult<ProductSpuDO> productSpuDOPageResult = productSpuMapper.selectPage(ProductSpuConvert.INSTANCE.convert(pageReqVO));
|
||||||
PageResult<AppSpuPageRespVO> pageResult = new PageResult<>();
|
PageResult<AppSpuPageRespVO> pageResult = new PageResult<>();
|
||||||
|
// TODO @芋艿 这里用convert如何解决
|
||||||
List<AppSpuPageRespVO> collect = productSpuDOPageResult.getList()
|
List<AppSpuPageRespVO> collect = productSpuDOPageResult.getList()
|
||||||
.stream()
|
.stream()
|
||||||
.map(ProductSpuConvert.INSTANCE::convertAppResp)
|
.map(ProductSpuConvert.INSTANCE::convertAppResp)
|
||||||
|
@ -1,163 +1,301 @@
|
|||||||
package cn.iocoder.yudao.module.product.service.spu;
|
package cn.iocoder.yudao.module.product.service.spu;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.framework.common.exception.ServiceException;
|
||||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
|
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
|
||||||
import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
|
import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
|
||||||
import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSpuCreateReqVO;
|
import cn.iocoder.yudao.module.product.controller.admin.property.vo.property.ProductPropertyRespVO;
|
||||||
import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSpuPageReqVO;
|
import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValueRespVO;
|
||||||
import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSpuRespVO;
|
import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuCreateOrUpdateReqVO;
|
||||||
import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSpuUpdateReqVO;
|
import cn.iocoder.yudao.module.product.controller.admin.spu.vo.*;
|
||||||
|
import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppSpuPageReqVO;
|
||||||
|
import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppSpuPageRespVO;
|
||||||
|
import cn.iocoder.yudao.module.product.convert.spu.ProductSpuConvert;
|
||||||
|
import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO;
|
||||||
import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO;
|
import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO;
|
||||||
import cn.iocoder.yudao.module.product.dal.mysql.spu.ProductSpuMapper;
|
import cn.iocoder.yudao.module.product.dal.mysql.spu.ProductSpuMapper;
|
||||||
import org.junit.jupiter.api.Disabled;
|
import cn.iocoder.yudao.module.product.enums.spu.ProductSpuSpecTypeEnum;
|
||||||
|
import cn.iocoder.yudao.module.product.enums.spu.ProductSpuStatusEnum;
|
||||||
|
import cn.iocoder.yudao.module.product.service.brand.ProductBrandServiceImpl;
|
||||||
|
import cn.iocoder.yudao.module.product.service.category.ProductCategoryServiceImpl;
|
||||||
|
import cn.iocoder.yudao.module.product.service.property.ProductPropertyService;
|
||||||
|
import cn.iocoder.yudao.module.product.service.property.ProductPropertyValueService;
|
||||||
|
import cn.iocoder.yudao.module.product.service.sku.ProductSkuServiceImpl;
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
|
import org.junit.jupiter.api.Assertions;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.mockito.Mockito;
|
||||||
|
import org.springframework.boot.test.mock.mockito.MockBean;
|
||||||
import org.springframework.context.annotation.Import;
|
import org.springframework.context.annotation.Import;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId;
|
|
||||||
import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;
|
import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;
|
||||||
import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException;
|
|
||||||
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo;
|
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo;
|
||||||
import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SPU_NOT_EXISTS;
|
|
||||||
import static org.junit.jupiter.api.Assertions.*;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link ProductSpuServiceImpl} 的单元测试类
|
* {@link ProductSpuServiceImpl} 的单元测试类
|
||||||
*
|
*
|
||||||
* @author 芋道源码
|
* @author 芋道源码
|
||||||
*/
|
*/
|
||||||
@Import(ProductSpuServiceImpl.class)
|
@Import(ProductSpuServiceImpl.class)
|
||||||
public class ProductSpuServiceImplTest extends BaseDbUnitTest {
|
public class ProductSpuServiceImplTest extends BaseDbUnitTest {
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
private ProductSpuServiceImpl spuService;
|
private ProductSpuServiceImpl productSpuService;
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
private ProductSpuMapper ProductSpuMapper;
|
private ProductSpuMapper productSpuMapper;
|
||||||
|
|
||||||
|
|
||||||
|
@MockBean
|
||||||
|
private ProductSkuServiceImpl productSkuService;
|
||||||
|
|
||||||
|
@MockBean
|
||||||
|
private ProductCategoryServiceImpl categoryService;
|
||||||
|
|
||||||
|
@MockBean
|
||||||
|
private ProductBrandServiceImpl brandService;
|
||||||
|
|
||||||
|
@MockBean
|
||||||
|
private ProductPropertyService productPropertyService;
|
||||||
|
|
||||||
|
@MockBean
|
||||||
|
private ProductPropertyValueService productPropertyValueService;
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCreateSpu_success() {
|
public void testCreateSpu_success() {
|
||||||
// 准备参数
|
// 准备参数
|
||||||
ProductSpuCreateReqVO reqVO = randomPojo(ProductSpuCreateReqVO.class);
|
ProductSpuCreateReqVO createReqVO = randomPojo(ProductSpuCreateReqVO.class, o -> {
|
||||||
|
o.setSpecType(ProductSpuSpecTypeEnum.DISABLE.getType());
|
||||||
|
o.setStatus(ProductSpuStatusEnum.ENABLE.getStatus());
|
||||||
|
});
|
||||||
|
|
||||||
|
// 校验SKU
|
||||||
|
List<ProductSkuCreateOrUpdateReqVO> skuCreateReqList = createReqVO.getSkus();
|
||||||
|
|
||||||
|
Long spu = productSpuService.createSpu(createReqVO);
|
||||||
|
ProductSpuDO productSpuDO = productSpuMapper.selectById(spu);
|
||||||
|
|
||||||
|
createReqVO.setMarketPrice(CollectionUtils.getMaxValue(skuCreateReqList, ProductSkuCreateOrUpdateReqVO::getMarketPrice));
|
||||||
|
createReqVO.setMaxPrice(CollectionUtils.getMaxValue(skuCreateReqList, ProductSkuCreateOrUpdateReqVO::getPrice));
|
||||||
|
createReqVO.setMinPrice(CollectionUtils.getMinValue(skuCreateReqList, ProductSkuCreateOrUpdateReqVO::getPrice));
|
||||||
|
createReqVO.setTotalStock(CollectionUtils.getSumValue(skuCreateReqList, ProductSkuCreateOrUpdateReqVO::getStock, Integer::sum));
|
||||||
|
|
||||||
|
assertPojoEquals(createReqVO, productSpuDO);
|
||||||
|
|
||||||
// 调用
|
|
||||||
Long spuId = spuService.createSpu(reqVO);
|
|
||||||
// 断言
|
|
||||||
assertNotNull(spuId);
|
|
||||||
// 校验记录的属性是否正确
|
|
||||||
ProductSpuDO spu = ProductSpuMapper.selectById(spuId);
|
|
||||||
assertPojoEquals(reqVO, spu);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testUpdateSpu_success() {
|
public void testUpdateSpu_success() {
|
||||||
// mock 数据
|
// 准备参数
|
||||||
ProductSpuDO dbSpu = randomPojo(ProductSpuDO.class);
|
ProductSpuDO createReqVO = randomPojo(ProductSpuDO.class);
|
||||||
ProductSpuMapper.insert(dbSpu);// @Sql: 先插入出一条存在的数据
|
productSpuMapper.insert(createReqVO);
|
||||||
// 准备参数
|
// 准备参数
|
||||||
ProductSpuUpdateReqVO reqVO = randomPojo(ProductSpuUpdateReqVO.class, o -> {
|
ProductSpuUpdateReqVO reqVO = randomPojo(ProductSpuUpdateReqVO.class, o -> {
|
||||||
o.setId(dbSpu.getId()); // 设置更新的 ID
|
o.setId(createReqVO.getId()); // 设置更新的 ID
|
||||||
|
o.setSpecType(ProductSpuSpecTypeEnum.DISABLE.getType());
|
||||||
|
o.setStatus(ProductSpuStatusEnum.DISABLE.getStatus());
|
||||||
});
|
});
|
||||||
|
|
||||||
// 调用
|
// 调用
|
||||||
spuService.updateSpu(reqVO);
|
productSpuService.updateSpu(reqVO);
|
||||||
|
|
||||||
|
List<ProductSkuCreateOrUpdateReqVO> skuCreateReqList = reqVO.getSkus();
|
||||||
|
reqVO.setMarketPrice(CollectionUtils.getMaxValue(skuCreateReqList, ProductSkuCreateOrUpdateReqVO::getMarketPrice));
|
||||||
|
reqVO.setMaxPrice(CollectionUtils.getMaxValue(skuCreateReqList, ProductSkuCreateOrUpdateReqVO::getPrice));
|
||||||
|
reqVO.setMinPrice(CollectionUtils.getMinValue(skuCreateReqList, ProductSkuCreateOrUpdateReqVO::getPrice));
|
||||||
|
reqVO.setTotalStock(CollectionUtils.getSumValue(skuCreateReqList, ProductSkuCreateOrUpdateReqVO::getStock, Integer::sum));
|
||||||
|
|
||||||
// 校验是否更新正确
|
// 校验是否更新正确
|
||||||
ProductSpuDO spu = ProductSpuMapper.selectById(reqVO.getId()); // 获取最新的
|
ProductSpuDO spu = productSpuMapper.selectById(reqVO.getId()); // 获取最新的
|
||||||
assertPojoEquals(reqVO, spu);
|
assertPojoEquals(reqVO, spu);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testUpdateSpu_notExists() {
|
public void testValidateSpuExists_exception() {
|
||||||
// 准备参数
|
ProductSpuUpdateReqVO reqVO = randomPojo(ProductSpuUpdateReqVO.class, o -> {
|
||||||
ProductSpuUpdateReqVO reqVO = randomPojo(ProductSpuUpdateReqVO.class);
|
o.setSpecType(ProductSpuSpecTypeEnum.DISABLE.getType());
|
||||||
|
o.setStatus(ProductSpuStatusEnum.DISABLE.getStatus());
|
||||||
// 调用, 并断言异常
|
|
||||||
assertServiceException(() -> spuService.updateSpu(reqVO), SPU_NOT_EXISTS);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testDeleteSpu_success() {
|
|
||||||
// mock 数据
|
|
||||||
ProductSpuDO dbSpu = randomPojo(ProductSpuDO.class);
|
|
||||||
ProductSpuMapper.insert(dbSpu);// @Sql: 先插入出一条存在的数据
|
|
||||||
// 准备参数
|
|
||||||
Long id = dbSpu.getId();
|
|
||||||
|
|
||||||
// 调用
|
|
||||||
spuService.deleteSpu(id);
|
|
||||||
// 校验数据不存在了
|
|
||||||
assertNull(ProductSpuMapper.selectById(id));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testDeleteSpu_notExists() {
|
|
||||||
// 准备参数
|
|
||||||
Long id = 1L;
|
|
||||||
|
|
||||||
// 调用, 并断言异常
|
|
||||||
assertServiceException(() -> spuService.deleteSpu(id), SPU_NOT_EXISTS);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
@Disabled // TODO 请修改 null 为需要的值,然后删除 @Disabled 注解
|
|
||||||
public void testGetSpuPage() {
|
|
||||||
// mock 数据
|
|
||||||
ProductSpuDO dbSpu = randomPojo(ProductSpuDO.class, o -> { // 等会查询到
|
|
||||||
o.setName(null);
|
|
||||||
o.setSellPoint(null);
|
|
||||||
o.setDescription(null);
|
|
||||||
o.setCategoryId(null);
|
|
||||||
o.setPicUrls(null);
|
|
||||||
o.setSort(null);
|
|
||||||
// o.setLikeCount(null);
|
|
||||||
// o.setPrice(null);
|
|
||||||
// o.setQuantity(null);
|
|
||||||
o.setStatus(null);
|
|
||||||
o.setCreateTime(null);
|
|
||||||
});
|
});
|
||||||
ProductSpuMapper.insert(dbSpu);
|
// 调用
|
||||||
// 测试 name 不匹配
|
Assertions.assertThrows(ServiceException.class, () -> productSpuService.updateSpu(reqVO));
|
||||||
ProductSpuMapper.insert(cloneIgnoreId(dbSpu, o -> o.setName(null)));
|
}
|
||||||
// 测试 sellPoint 不匹配
|
|
||||||
ProductSpuMapper.insert(cloneIgnoreId(dbSpu, o -> o.setSellPoint(null)));
|
@Test
|
||||||
// 测试 description 不匹配
|
void deleteSpu() {
|
||||||
ProductSpuMapper.insert(cloneIgnoreId(dbSpu, o -> o.setDescription(null)));
|
|
||||||
// 测试 categoryId 不匹配
|
|
||||||
ProductSpuMapper.insert(cloneIgnoreId(dbSpu, o -> o.setCategoryId(null)));
|
|
||||||
// 测试 picUrls 不匹配
|
|
||||||
ProductSpuMapper.insert(cloneIgnoreId(dbSpu, o -> o.setPicUrls(null)));
|
|
||||||
// 测试 sort 不匹配
|
|
||||||
ProductSpuMapper.insert(cloneIgnoreId(dbSpu, o -> o.setSort(null)));
|
|
||||||
// 测试 likeCount 不匹配
|
|
||||||
// ProductSpuMapper.insert(cloneIgnoreId(dbSpu, o -> o.setLikeCount(null)));
|
|
||||||
// 测试 price 不匹配
|
|
||||||
// ProductSpuMapper.insert(cloneIgnoreId(dbSpu, o -> o.setPrice(null)));
|
|
||||||
// 测试 quantity 不匹配
|
|
||||||
// ProductSpuMapper.insert(cloneIgnoreId(dbSpu, o -> o.setQuantity(null)));
|
|
||||||
// 测试 status 不匹配
|
|
||||||
ProductSpuMapper.insert(cloneIgnoreId(dbSpu, o -> o.setStatus(null)));
|
|
||||||
// 测试 createTime 不匹配
|
|
||||||
ProductSpuMapper.insert(cloneIgnoreId(dbSpu, o -> o.setCreateTime(null)));
|
|
||||||
// 准备参数
|
// 准备参数
|
||||||
ProductSpuPageReqVO reqVO = new ProductSpuPageReqVO();
|
ProductSpuDO createReqVO = randomPojo(ProductSpuDO.class);
|
||||||
reqVO.setName(null);
|
productSpuMapper.insert(createReqVO);
|
||||||
reqVO.setSellPoint(null);
|
|
||||||
reqVO.setDescription(null);
|
|
||||||
reqVO.setCategoryId(null);
|
|
||||||
reqVO.setPicUrls(null);
|
|
||||||
reqVO.setSort(null);
|
|
||||||
reqVO.setLikeCount(null);
|
|
||||||
reqVO.setPrice(null);
|
|
||||||
reqVO.setQuantity(null);
|
|
||||||
reqVO.setStatus(null);
|
|
||||||
reqVO.setCreateTime(null);
|
|
||||||
|
|
||||||
// 调用
|
// 调用
|
||||||
PageResult<ProductSpuRespVO> pageResult = spuService.getSpuPage(reqVO);
|
productSpuService.deleteSpu(createReqVO.getId());
|
||||||
// 断言
|
|
||||||
assertEquals(1, pageResult.getTotal());
|
Assertions.assertNull(productSpuMapper.selectById(createReqVO.getId()));
|
||||||
assertEquals(1, pageResult.getList().size());
|
}
|
||||||
assertPojoEquals(dbSpu, pageResult.getList().get(0));
|
|
||||||
|
@Test
|
||||||
|
void getSpuDetail() {
|
||||||
|
// 准备spu参数
|
||||||
|
ProductSpuDO createReqVO = randomPojo(ProductSpuDO.class, o -> {
|
||||||
|
o.setSpecType(ProductSpuSpecTypeEnum.DISABLE.getType());
|
||||||
|
});
|
||||||
|
productSpuMapper.insert(createReqVO);
|
||||||
|
|
||||||
|
// 创建两个属性
|
||||||
|
ArrayList<ProductPropertyRespVO> productPropertyRespVOS = Lists.newArrayList(
|
||||||
|
randomPojo(ProductPropertyRespVO.class),
|
||||||
|
randomPojo(ProductPropertyRespVO.class));
|
||||||
|
|
||||||
|
// 所有属性值
|
||||||
|
ArrayList<ProductPropertyValueRespVO> productPropertyValueRespVO = new ArrayList<>();
|
||||||
|
|
||||||
|
// 每个属性创建属性值
|
||||||
|
productPropertyRespVOS.forEach(v -> {
|
||||||
|
ProductPropertyValueRespVO productPropertyValueRespVO1 = randomPojo(ProductPropertyValueRespVO.class, o -> o.setPropertyId(v.getId()));
|
||||||
|
productPropertyValueRespVO.add(productPropertyValueRespVO1);
|
||||||
|
});
|
||||||
|
|
||||||
|
// 属性值建立笛卡尔积
|
||||||
|
Map<Long, List<ProductPropertyValueRespVO>> collect = productPropertyValueRespVO.stream().collect(Collectors.groupingBy(ProductPropertyValueRespVO::getPropertyId));
|
||||||
|
List<List<ProductPropertyValueRespVO>> lists = cartesianProduct(Lists.newArrayList(collect.values()));
|
||||||
|
|
||||||
|
// 准备sku参数
|
||||||
|
ArrayList<ProductSkuDO> productSkuDOS = Lists.newArrayList();
|
||||||
|
lists.forEach(pp -> {
|
||||||
|
List<ProductSkuDO.Property> property = pp.stream().map(ppv -> new ProductSkuDO.Property(ppv.getPropertyId(), ppv.getId())).collect(Collectors.toList());
|
||||||
|
ProductSkuDO productSkuDO = randomPojo(ProductSkuDO.class, o -> {
|
||||||
|
o.setProperties(property);
|
||||||
|
});
|
||||||
|
productSkuDOS.add(productSkuDO);
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
Mockito.when(productSkuService.getSkusBySpuId(createReqVO.getId())).thenReturn(productSkuDOS);
|
||||||
|
Mockito.when(productPropertyValueService.getPropertyValueListByPropertyId(new ArrayList<>(collect.keySet()))).thenReturn(productPropertyValueRespVO);
|
||||||
|
Mockito.when(productPropertyService.getPropertyList(new ArrayList<>(collect.keySet()))).thenReturn(productPropertyRespVOS);
|
||||||
|
|
||||||
|
// 调用
|
||||||
|
ProductSpuDetailRespVO spuDetail = productSpuService.getSpuDetail(createReqVO.getId());
|
||||||
|
|
||||||
|
assertPojoEquals(createReqVO, spuDetail);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void getSpu() {
|
||||||
|
// 准备参数
|
||||||
|
ProductSpuDO createReqVO = randomPojo(ProductSpuDO.class);
|
||||||
|
productSpuMapper.insert(createReqVO);
|
||||||
|
|
||||||
|
ProductSpuRespVO spu = productSpuService.getSpu(createReqVO.getId());
|
||||||
|
assertPojoEquals(createReqVO, spu);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void getSpuList() {
|
||||||
|
// 准备参数
|
||||||
|
ArrayList<ProductSpuDO> createReqVO = Lists.newArrayList(randomPojo(ProductSpuDO.class), randomPojo(ProductSpuDO.class));
|
||||||
|
productSpuMapper.insertBatch(createReqVO);
|
||||||
|
|
||||||
|
// 调用
|
||||||
|
List<ProductSpuDO> spuList = productSpuService.getSpuList(createReqVO.stream().map(ProductSpuDO::getId).collect(Collectors.toList()));
|
||||||
|
Assertions.assertIterableEquals(createReqVO, spuList);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void getSpuPage() {
|
||||||
|
// 准备参数
|
||||||
|
ProductSpuDO createReqVO = randomPojo(ProductSpuDO.class);
|
||||||
|
productSpuMapper.insert(createReqVO);
|
||||||
|
|
||||||
|
ArrayList<ProductSkuDO> remindSpuIds = Lists.newArrayList(
|
||||||
|
// randomPojo(ProductSkuDO.class, o -> o.setSpuId(createReqVO.getId())),
|
||||||
|
// randomPojo(ProductSkuDO.class, o -> o.setSpuId(createReqVO.getId()))
|
||||||
|
);
|
||||||
|
|
||||||
|
Mockito.when(productSkuService.getRemindSpuIds()).thenReturn(remindSpuIds);
|
||||||
|
|
||||||
|
// 调用
|
||||||
|
ProductSpuPageReqVO productSpuPageReqVO = new ProductSpuPageReqVO();
|
||||||
|
productSpuPageReqVO.setTabStatus(2);
|
||||||
|
|
||||||
|
PageResult<ProductSpuRespVO> spuPage = productSpuService.getSpuPage(productSpuPageReqVO);
|
||||||
|
|
||||||
|
ArrayList<Long> resultRemindSpuIds = new ArrayList<>();
|
||||||
|
resultRemindSpuIds.add(null);
|
||||||
|
PageResult<ProductSpuRespVO> result = ProductSpuConvert.INSTANCE.convertPage(productSpuMapper.selectPage(productSpuPageReqVO, resultRemindSpuIds));
|
||||||
|
Assertions.assertIterableEquals(result.getList(), spuPage.getList());
|
||||||
|
Assertions.assertEquals(spuPage.getTotal(), result.getTotal());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testGetSpuPage() {
|
||||||
|
// 准备参数
|
||||||
|
ProductSpuDO createReqVO = randomPojo(ProductSpuDO.class, o -> {
|
||||||
|
o.setCategoryId(2L);
|
||||||
|
});
|
||||||
|
productSpuMapper.insert(createReqVO);
|
||||||
|
|
||||||
|
ArrayList<ProductSkuDO> remindSpuIds = Lists.newArrayList(
|
||||||
|
// randomPojo(ProductSkuDO.class, o -> o.setSpuId(createReqVO.getId())),
|
||||||
|
// randomPojo(ProductSkuDO.class, o -> o.setSpuId(createReqVO.getId()))
|
||||||
|
);
|
||||||
|
|
||||||
|
Mockito.when(productSkuService.getRemindSpuIds()).thenReturn(remindSpuIds);
|
||||||
|
|
||||||
|
// 调用
|
||||||
|
AppSpuPageReqVO appSpuPageReqVO = new AppSpuPageReqVO();
|
||||||
|
appSpuPageReqVO.setCategoryId(2L);
|
||||||
|
|
||||||
|
PageResult<AppSpuPageRespVO> spuPage = productSpuService.getSpuPage(appSpuPageReqVO);
|
||||||
|
|
||||||
|
PageResult<ProductSpuDO> result = productSpuMapper.selectPage(
|
||||||
|
ProductSpuConvert.INSTANCE.convert(appSpuPageReqVO));
|
||||||
|
|
||||||
|
List<AppSpuPageRespVO> collect = result.getList()
|
||||||
|
.stream()
|
||||||
|
.map(ProductSpuConvert.INSTANCE::convertAppResp)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
Assertions.assertIterableEquals(collect, spuPage.getList());
|
||||||
|
Assertions.assertEquals(spuPage.getTotal(), result.getTotal());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生成笛卡尔积
|
||||||
|
*
|
||||||
|
* @param data 数据
|
||||||
|
* @return 笛卡尔积
|
||||||
|
*/
|
||||||
|
public static <T> List<List<T>> cartesianProduct(List<List<T>> data) {
|
||||||
|
List<List<T>> res = null; // 结果集(当前为第N个List,则该处存放的就为前N-1个List的笛卡尔积集合)
|
||||||
|
for (List<T> list : data) { // 遍历数据
|
||||||
|
List<List<T>> temp = new ArrayList<>(); // 临时结果集,存放本次循环后生成的笛卡尔积集合
|
||||||
|
if (res == null) { // 结果集为null表示第一次循环既list为第一个List
|
||||||
|
for (T t : list) { // 便利第一个List
|
||||||
|
// 利用stream生成List,第一个List的笛卡尔积集合约等于自己本身(需要创建一个List并把对象添加到当中),存放到临时结果集
|
||||||
|
temp.add(Stream.of(t).collect(Collectors.toList()));
|
||||||
|
}
|
||||||
|
res = temp; // 将临时结果集赋值给结果集
|
||||||
|
continue; // 跳过本次循环
|
||||||
|
}
|
||||||
|
// 不为第一个List,计算前面的集合(笛卡尔积)和当前List的笛卡尔积集合
|
||||||
|
for (T t : list) { // 便利
|
||||||
|
for (List<T> rl : res) { // 便利前面的笛卡尔积集合
|
||||||
|
// 利用stream生成List
|
||||||
|
temp.add(Stream.concat(rl.stream(), Stream.of(t)).collect(Collectors.toList()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
res = temp; // 将临时结果集赋值给结果集
|
||||||
|
}
|
||||||
|
// 返回结果
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
DELETE FROM "product_category";
|
DELETE FROM "product_sku";
|
||||||
|
|
||||||
DELETE FROM "product_brand";
|
DELETE FROM "product_spu";
|
@ -1,30 +1,54 @@
|
|||||||
CREATE TABLE IF NOT EXISTS "product_category" (
|
CREATE TABLE IF NOT EXISTS `product_sku` (
|
||||||
"id" bigint(20) NOT NULL GENERATED BY DEFAULT AS IDENTITY,
|
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键',
|
||||||
"parent_id" bigint(20) NOT NULL,
|
`spu_id` bigint NOT NULL COMMENT 'spu编号',
|
||||||
"name" varchar(255) NOT NULL,
|
`tenant_id` bigint NOT NULL DEFAULT '0' COMMENT '租户编号',
|
||||||
"pic_url" varchar(255) NOT NULL,
|
`name` varchar(128) DEFAULT NULL COMMENT '商品 SKU 名字',
|
||||||
"sort" int(11) NOT NULL,
|
`properties` varchar(128) DEFAULT NULL COMMENT '规格值数组-json格式, [{propertId: , valueId: }, {propertId: , valueId: }]',
|
||||||
"description" varchar(1024) NOT NULL,
|
`price` int NOT NULL DEFAULT '-1' COMMENT '销售价格,单位:分',
|
||||||
"status" tinyint(4) NOT NULL,
|
`market_price` int DEFAULT NULL COMMENT '市场价',
|
||||||
"creator" varchar(64) DEFAULT '',
|
`cost_price` int NOT NULL DEFAULT '-1' COMMENT '成本价,单位: 分',
|
||||||
"create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
`pic_url` varchar(128) NOT NULL COMMENT '图片地址',
|
||||||
"updater" varchar(64) DEFAULT '',
|
`stock` int DEFAULT NULL COMMENT '库存',
|
||||||
"update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
`warn_stock` int DEFAULT NULL COMMENT '预警库存',
|
||||||
"deleted" bit NOT NULL DEFAULT FALSE,
|
`volume` double DEFAULT NULL COMMENT '商品体积',
|
||||||
PRIMARY KEY ("id")
|
`weight` double DEFAULT NULL COMMENT '商品重量',
|
||||||
) COMMENT '商品分类';
|
`bar_code` varchar(64) DEFAULT NULL COMMENT '条形码',
|
||||||
|
`status` tinyint DEFAULT NULL COMMENT '状态: 0-正常 1-禁用',
|
||||||
|
`create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||||
|
`update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||||
|
`creator` varchar(64) DEFAULT NULL COMMENT '创建人',
|
||||||
|
`updater` double DEFAULT NULL COMMENT '更新人',
|
||||||
|
`deleted` bit(1) NOT NULL DEFAULT 0 COMMENT '是否删除',
|
||||||
|
PRIMARY KEY (`id`)
|
||||||
|
) COMMENT '商品sku';
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS "product_brand" (
|
|
||||||
"id" bigint(20) NOT NULL GENERATED BY DEFAULT AS IDENTITY,
|
CREATE TABLE IF NOT EXISTS `product_spu` (
|
||||||
"name" varchar(255) NOT NULL,
|
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键',
|
||||||
"pic_url" varchar(255) NOT NULL,
|
`tenant_id` bigint NOT NULL DEFAULT '0' COMMENT '租户编号',
|
||||||
"sort" int(11),
|
`brand_id` bigint DEFAULT NULL COMMENT '商品品牌编号',
|
||||||
"description" varchar(1024),
|
`category_id` bigint NOT NULL COMMENT '分类id',
|
||||||
"status" tinyint(4) NOT NULL,
|
`spec_type` int NOT NULL COMMENT '规格类型:0 单规格 1 多规格',
|
||||||
"creator" varchar(64) DEFAULT '',
|
`code` varchar(128) DEFAULT NULL COMMENT '商品编码',
|
||||||
"create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
`name` varchar(128) NOT NULL COMMENT '商品名称',
|
||||||
"updater" varchar(64) DEFAULT '',
|
`sell_point` varchar(128) DEFAULT NULL COMMENT '卖点',
|
||||||
"update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
`description` text COMMENT '描述',
|
||||||
"deleted" bit NOT NULL DEFAULT FALSE,
|
`pic_urls` varchar(1024) DEFAULT '' COMMENT '商品轮播图地址数组,以逗号分隔最多上传15张',
|
||||||
PRIMARY KEY ("id")
|
`video_url` varchar(128) DEFAULT NULL COMMENT '商品视频',
|
||||||
) COMMENT '商品品牌';
|
`market_price` int DEFAULT NULL COMMENT '市场价,单位使用:分',
|
||||||
|
`min_price` int DEFAULT NULL COMMENT '最小价格,单位使用:分',
|
||||||
|
`max_price` int DEFAULT NULL COMMENT '最大价格,单位使用:分',
|
||||||
|
`total_stock` int NOT NULL DEFAULT '0' COMMENT '总库存',
|
||||||
|
`show_stock` int DEFAULT '0' COMMENT '是否展示库存',
|
||||||
|
`sales_count` int DEFAULT '0' COMMENT '商品销量',
|
||||||
|
`virtual_sales_count` int DEFAULT '0' COMMENT '虚拟销量',
|
||||||
|
`click_count` int DEFAULT '0' COMMENT '商品点击量',
|
||||||
|
`status` bit(1) DEFAULT NULL COMMENT '上下架状态: 0 上架(开启) 1 下架(禁用)-1 回收',
|
||||||
|
`sort` int NOT NULL DEFAULT '0' COMMENT '排序字段',
|
||||||
|
`create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||||
|
`update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||||
|
`creator` varchar(64) DEFAULT NULL COMMENT '创建人',
|
||||||
|
`updater` varchar(64) DEFAULT NULL COMMENT '更新人',
|
||||||
|
`deleted` bit(1) NOT NULL DEFAULT 0 COMMENT '是否删除',
|
||||||
|
PRIMARY KEY (`id`)
|
||||||
|
) COMMENT '商品spu';
|
||||||
|
Loading…
Reference in New Issue
Block a user