From 9d5d8c9527ca81c1a41633565d7cb62ee55d92c2 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Fri, 23 Oct 2026 01:14:19 +0800 Subject: [PATCH] fix(product): 修正虚拟评价创建契约并启用商品评价单测 --- yudao-module-mall/yudao-module-product/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/vo/ProductCommentCreateReqVO.java | 6 ------ yudao-module-mall/yudao-module-product/src/main/java/cn/iocoder/yudao/module/product/convert/comment/ProductCommentConvert.java | 1 + yudao-module-mall/yudao-module-product/src/test/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentServiceImplTest.java | 403 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------------------------------------------------------------------------------------------------------------- yudao-module-mall/yudao-module-product/src/test/resources/sql/create_tables.sql | 36 +++++++++++++++++++----------------- 4 files changed, 311 insertions(+), 135 deletions(-) diff --git a/yudao-module-mall/yudao-module-product/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/vo/ProductCommentCreateReqVO.java b/yudao-module-mall/yudao-module-product/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/vo/ProductCommentCreateReqVO.java index b411db0..06b5d8f 100644 --- a/yudao-module-mall/yudao-module-product/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/vo/ProductCommentCreateReqVO.java +++ b/yudao-module-mall/yudao-module-product/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/vo/ProductCommentCreateReqVO.java @@ -11,12 +11,6 @@ import java.util.List; @Data public class ProductCommentCreateReqVO { - @Schema(description = "评价人", requiredMode = Schema.RequiredMode.REQUIRED, example = "16868") - private Long userId; - - @Schema(description = "评价订单项", requiredMode = Schema.RequiredMode.REQUIRED, example = "19292") - private Long orderItemId; - @Schema(description = "评价人名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "小姑凉") @NotNull(message = "评价人名称不能为空") private String userNickname; diff --git a/yudao-module-mall/yudao-module-product/src/main/java/cn/iocoder/yudao/module/product/convert/comment/ProductCommentConvert.java b/yudao-module-mall/yudao-module-product/src/main/java/cn/iocoder/yudao/module/product/convert/comment/ProductCommentConvert.java index 7a3a3c0..ecdb3d7 100644 --- a/yudao-module-mall/yudao-module-product/src/main/java/cn/iocoder/yudao/module/product/convert/comment/ProductCommentConvert.java +++ b/yudao-module-mall/yudao-module-product/src/main/java/cn/iocoder/yudao/module/product/convert/comment/ProductCommentConvert.java @@ -40,6 +40,7 @@ public interface ProductCommentConvert { } default ProductCommentDO convert(ProductCommentCreateReqVO createReq, ProductSpuDO spu, ProductSkuDO sku) { + // 管理后台添加的是虚拟评价,不关联会员和订单,userId 固定为 0:https://github.com/YunaiV/ruoyi-vue-pro/issues/1277 ProductCommentDO comment = BeanUtils.toBean(createReq, ProductCommentDO.class) .setVisible(true).setUserId(0L).setAnonymous(false) .setScores(convertScores(createReq.getDescriptionScores(), createReq.getBenefitScores())); diff --git a/yudao-module-mall/yudao-module-product/src/test/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentServiceImplTest.java b/yudao-module-mall/yudao-module-product/src/test/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentServiceImplTest.java index 0e853f9..b55ecaf 100644 --- a/yudao-module-mall/yudao-module-product/src/test/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentServiceImplTest.java +++ b/yudao-module-mall/yudao-module-product/src/test/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentServiceImplTest.java @@ -1,35 +1,45 @@ package cn.iocoder.yudao.module.product.service.comment; -import cn.hutool.core.date.DateUtil; -import cn.hutool.core.util.RandomUtil; import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.framework.common.util.object.BeanUtils; +import cn.iocoder.yudao.framework.common.util.collection.ArrayUtils; import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; +import cn.iocoder.yudao.module.member.api.user.MemberUserApi; +import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO; +import cn.iocoder.yudao.module.product.api.comment.dto.ProductCommentCreateReqDTO; +import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentCreateReqVO; import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentPageReqVO; import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentReplyReqVO; -import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentRespVO; import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentUpdateVisibleReqVO; import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentPageReqVO; import cn.iocoder.yudao.module.product.dal.dataobject.comment.ProductCommentDO; +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.mysql.comment.ProductCommentMapper; import cn.iocoder.yudao.module.product.enums.comment.ProductCommentScoresEnum; import cn.iocoder.yudao.module.product.service.sku.ProductSkuService; import cn.iocoder.yudao.module.product.service.spu.ProductSpuService; import jakarta.annotation.Resource; -import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.springframework.context.annotation.Import; -import org.springframework.context.annotation.Lazy; +import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder; import org.springframework.test.context.bean.override.mockito.MockitoBean; -import java.time.LocalDateTime; -import java.util.Date; +import java.util.List; +import java.util.function.Consumer; +import static cn.hutool.core.util.RandomUtil.randomEle; +import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.buildBetweenTime; +import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.buildTime; 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.RandomUtils.randomPojo; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; +import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException; +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*; +import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.*; +import static java.util.Collections.singletonList; +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.*; // TODO 芋艿:单测详细 review 下 /** @@ -37,159 +47,328 @@ import static org.junit.jupiter.api.Assertions.assertFalse; * * @author wangzhs */ -@Disabled // TODO 芋艿:后续 fix 补充的单测 +// DONE 芋艿:后续 fix 补充的单测 @Import(ProductCommentServiceImpl.class) public class ProductCommentServiceImplTest extends BaseDbUnitTest { @Resource - private ProductCommentMapper productCommentMapper; + private ProductCommentServiceImpl productCommentService; @Resource - @Lazy - private ProductCommentServiceImpl productCommentService; + private ProductCommentMapper productCommentMapper; @MockitoBean private ProductSpuService productSpuService; @MockitoBean private ProductSkuService productSkuService; + @MockitoBean + private MemberUserApi memberUserApi; + + // ========== 管理后台添加虚拟评价 ========== + + @Test + public void testCreateComment_success() { + // 准备参数 + ProductCommentCreateReqVO reqVO = randomPojo(ProductCommentCreateReqVO.class, o -> o + .setDescriptionScores(ProductCommentScoresEnum.FIVE.getScores()) + .setBenefitScores(ProductCommentScoresEnum.FOUR.getScores())); + // mock 方法 + ProductSkuDO sku = mockSku(reqVO.getSkuId()); + ProductSpuDO spu = mockSpu(sku.getSpuId()); - public String generateNo() { - return DateUtil.format(new Date(), "yyyyMMddHHmmss") + RandomUtil.randomInt(100000, 999999); + // 调用 + productCommentService.createComment(reqVO); + // 断言:虚拟评价不关联会员和订单 + List comments = productCommentMapper.selectList(); + assertEquals(1, comments.size()); + ProductCommentDO comment = comments.get(0); + assertPojoEquals(reqVO, comment); + assertEquals(0L, comment.getUserId()); + assertNull(comment.getOrderId()); + assertNull(comment.getOrderItemId()); + assertTrue(comment.getVisible()); + assertFalse(comment.getAnonymous()); + assertEquals(4, comment.getScores()); // (5 + 4) / 2 向下取整 + // 断言:商品信息 + assertEquals(spu.getId(), comment.getSpuId()); + assertEquals(spu.getName(), comment.getSpuName()); + assertEquals(sku.getPicUrl(), comment.getSkuPicUrl()); + assertEquals(sku.getProperties(), comment.getSkuProperties()); + } + + @Test + public void testCreateComment_ignoreUserIdAndOrderItemId() throws Exception { + // 准备参数:旧调用方仍传入 userId、orderItemId,使用 Spring MVC 默认的 Jackson2ObjectMapperBuilder 反序列化 + String json = "{\"userId\":968,\"orderItemId\":1024,\"skuId\":1,\"userNickname\":\"芋艿\"," + + "\"userAvatar\":\"https://www.iocoder.cn/1.png\",\"descriptionScores\":5,\"benefitScores\":5," + + "\"content\":\"好评\",\"picUrls\":[]}"; + ProductCommentCreateReqVO reqVO = Jackson2ObjectMapperBuilder.json().build() + .readValue(json, ProductCommentCreateReqVO.class); + // mock 方法 + mockSpu(mockSku(reqVO.getSkuId()).getSpuId()); + + // 调用 + productCommentService.createComment(reqVO); + // 断言 + ProductCommentDO comment = productCommentMapper.selectOne(ProductCommentDO::getSkuId, 1L); + assertEquals("芋艿", comment.getUserNickname()); + assertEquals(0L, comment.getUserId()); + assertNull(comment.getOrderItemId()); } - public Long generateId() { - return RandomUtil.randomLong(100000, 999999); + @Test + public void testCreateComment_skuNotExists() { + // 准备参数 + ProductCommentCreateReqVO reqVO = randomPojo(ProductCommentCreateReqVO.class); + + // 调用,并断言异常 + assertServiceException(() -> productCommentService.createComment(reqVO), SKU_NOT_EXISTS); + assertEquals(0L, productCommentMapper.selectCount()); } + // ========== 会员评价订单项 ========== + @Test - public void testCreateCommentAndGet_success() { - // mock 测试 - ProductCommentDO productComment = randomPojo(ProductCommentDO.class); - productCommentMapper.insert(productComment); + public void testCreateCommentByMember_success() { + // 准备参数 + ProductCommentCreateReqDTO reqDTO = randomPojo(ProductCommentCreateReqDTO.class, o -> o + .setDescriptionScores(ProductCommentScoresEnum.THREE.getScores()) + .setBenefitScores(ProductCommentScoresEnum.FOUR.getScores())); + // mock 数据:同一 SKU 已有虚拟评价,不影响会员评价 + productCommentMapper.insert(randomCommentDO(o -> o.setUserId(0L).setOrderId(null).setOrderItemId(null) + .setSkuId(reqDTO.getSkuId()))); + // mock 方法 + ProductSkuDO sku = mockSku(reqDTO.getSkuId()); + ProductSpuDO spu = mockSpu(sku.getSpuId()); + MemberUserRespDTO user = randomPojo(MemberUserRespDTO.class, o -> o.setId(reqDTO.getUserId())); + when(memberUserApi.getUser(eq(reqDTO.getUserId()))).thenReturn(user); + // 调用 + Long commentId = productCommentService.createComment(reqDTO); // 断言 - // 校验记录的属性是否正确 - ProductCommentDO comment = productCommentMapper.selectById(productComment.getId()); - assertPojoEquals(productComment, comment); + ProductCommentDO comment = productCommentMapper.selectById(commentId); + assertPojoEquals(reqDTO, comment); + assertEquals(user.getNickname(), comment.getUserNickname()); + assertEquals(user.getAvatar(), comment.getUserAvatar()); + assertEquals(3, comment.getScores()); // (3 + 4) / 2 向下取整 + assertEquals(spu.getId(), comment.getSpuId()); + assertEquals(spu.getName(), comment.getSpuName()); + assertEquals(sku.getPicUrl(), comment.getSkuPicUrl()); + assertEquals(sku.getProperties(), comment.getSkuProperties()); } @Test - public void testGetCommentPage_success() { + public void testCreateCommentByMember_orderExists() { + // mock 数据:该会员已评价该订单项 + ProductCommentDO dbComment = randomCommentDO(); + productCommentMapper.insert(dbComment); // 准备参数 - ProductCommentDO productComment = randomPojo(ProductCommentDO.class, o -> { + ProductCommentCreateReqDTO reqDTO = randomPojo(ProductCommentCreateReqDTO.class, o -> o + .setUserId(dbComment.getUserId()).setOrderItemId(dbComment.getOrderItemId())); + // mock 方法 + mockSpu(mockSku(reqDTO.getSkuId()).getSpuId()); + + // 调用,并断言异常 + assertServiceException(() -> productCommentService.createComment(reqDTO), COMMENT_ORDER_EXISTS); + assertEquals(1L, productCommentMapper.selectCount()); + verify(memberUserApi, never()).getUser(any()); + } + + // ========== 查询评价 ========== + + @Test + public void testGetComment_success() { + // mock 数据 + ProductCommentDO dbComment = randomCommentDO(); + productCommentMapper.insert(dbComment); + + // 调用 + ProductCommentDO comment = productCommentService.getComment(dbComment.getId()); + // 断言 + assertPojoEquals(dbComment, comment); + } + + @Test + public void testGetComment_notExists() { + // 调用,并断言异常 + assertServiceException(() -> productCommentService.getComment(randomLongId()), COMMENT_NOT_EXISTS); + } + + @Test + public void testGetCommentPage_success() { + // mock 数据 + ProductCommentDO dbComment = randomCommentDO(o -> { // 等会查询到 o.setUserNickname("王二狗"); + o.setOrderId(1L); + o.setSpuId(2L); o.setSpuName("感冒药"); o.setScores(ProductCommentScoresEnum.FOUR.getScores()); o.setReplyStatus(Boolean.TRUE); - o.setVisible(Boolean.TRUE); - o.setId(generateId()); - o.setUserId(generateId()); - o.setAnonymous(Boolean.TRUE); - o.setOrderId(generateId()); - o.setOrderItemId(generateId()); - o.setSpuId(generateId()); - o.setSkuId(generateId()); - o.setDescriptionScores(ProductCommentScoresEnum.FOUR.getScores()); - o.setBenefitScores(ProductCommentScoresEnum.FOUR.getScores()); - o.setContent("真好吃"); - o.setReplyUserId(generateId()); - o.setReplyContent("确实"); - o.setReplyTime(LocalDateTime.now()); - o.setCreateTime(LocalDateTime.now()); - o.setUpdateTime(LocalDateTime.now()); + o.setCreateTime(buildTime(2023, 2, 1)); + o.setSkuProperties(null); // ProductSkuDO.Property 不可序列化,cloneIgnoreId 无法深拷贝 }); - productCommentMapper.insert(productComment); - - Long orderId = productComment.getOrderId(); - Long spuId = productComment.getSpuId(); - + productCommentMapper.insert(dbComment); // 测试 userNickname 不匹配 - productCommentMapper.insert(cloneIgnoreId(productComment, o -> o.setUserNickname("王三").setScores(ProductCommentScoresEnum.ONE.getScores()))); + productCommentMapper.insert(cloneIgnoreId(dbComment, o -> o.setUserNickname("王三"))); // 测试 orderId 不匹配 - productCommentMapper.insert(cloneIgnoreId(productComment, o -> o.setOrderId(generateId()))); + productCommentMapper.insert(cloneIgnoreId(dbComment, o -> o.setOrderId(10L))); // 测试 spuId 不匹配 - productCommentMapper.insert(cloneIgnoreId(productComment, o -> o.setSpuId(generateId()))); + productCommentMapper.insert(cloneIgnoreId(dbComment, o -> o.setSpuId(20L))); // 测试 spuName 不匹配 - productCommentMapper.insert(cloneIgnoreId(productComment, o -> o.setSpuName("感康"))); + productCommentMapper.insert(cloneIgnoreId(dbComment, o -> o.setSpuName("感康"))); // 测试 scores 不匹配 - productCommentMapper.insert(cloneIgnoreId(productComment, o -> o.setScores(ProductCommentScoresEnum.ONE.getScores()))); - // 测试 replied 不匹配 - productCommentMapper.insert(cloneIgnoreId(productComment, o -> o.setReplyStatus(Boolean.FALSE))); - // 测试 visible 不匹配 - productCommentMapper.insert(cloneIgnoreId(productComment, o -> o.setVisible(Boolean.FALSE))); + productCommentMapper.insert(cloneIgnoreId(dbComment, o -> o.setScores(ProductCommentScoresEnum.ONE.getScores()))); + // 测试 replyStatus 不匹配 + productCommentMapper.insert(cloneIgnoreId(dbComment, o -> o.setReplyStatus(Boolean.FALSE))); + // 测试 createTime 不匹配 + productCommentMapper.insert(cloneIgnoreId(dbComment, o -> o.setCreateTime(buildTime(2023, 3, 1)))); + // 准备参数 + ProductCommentPageReqVO reqVO = new ProductCommentPageReqVO(); + reqVO.setUserNickname("王二"); + reqVO.setOrderId(1L); + reqVO.setSpuId(2L); + reqVO.setSpuName("感冒"); + reqVO.setScores(ProductCommentScoresEnum.FOUR.getScores()); + reqVO.setReplyStatus(Boolean.TRUE); + reqVO.setCreateTime(buildBetweenTime(2023, 1, 1, 2023, 2, 28)); // 调用 - ProductCommentPageReqVO productCommentPageReqVO = new ProductCommentPageReqVO(); - productCommentPageReqVO.setUserNickname("王二"); - productCommentPageReqVO.setOrderId(orderId); - productCommentPageReqVO.setSpuId(spuId); - productCommentPageReqVO.setSpuName("感冒药"); - productCommentPageReqVO.setScores(ProductCommentScoresEnum.FOUR.getScores()); - productCommentPageReqVO.setReplyStatus(Boolean.TRUE); - - PageResult commentPage = productCommentService.getCommentPage(productCommentPageReqVO); - PageResult result = BeanUtils.toBean(productCommentMapper.selectPage(productCommentPageReqVO), - ProductCommentRespVO.class); - assertEquals(result.getTotal(), commentPage.getTotal()); + PageResult pageResult = productCommentService.getCommentPage(reqVO); + // 断言 + assertEquals(1, pageResult.getTotal()); + assertEquals(1, pageResult.getList().size()); + assertPojoEquals(dbComment, pageResult.getList().get(0)); + } - PageResult all = productCommentService.getCommentPage(new ProductCommentPageReqVO()); - assertEquals(8, all.getTotal()); + @Test + public void testGetAppCommentPage_success() { + // mock 数据 + ProductCommentDO goodComment = randomCommentDO(o -> o.setSpuId(1L).setVisible(Boolean.TRUE) + .setScores(ProductCommentScoresEnum.FIVE.getScores()) + .setSkuProperties(null)); // ProductSkuDO.Property 不可序列化,cloneIgnoreId 无法深拷贝 + productCommentMapper.insert(goodComment); + ProductCommentDO mediocreComment = cloneIgnoreId(goodComment, o -> o.setScores(ProductCommentScoresEnum.THREE.getScores())); + productCommentMapper.insert(mediocreComment); + ProductCommentDO negativeComment = cloneIgnoreId(goodComment, o -> o.setScores(ProductCommentScoresEnum.ONE.getScores())); + productCommentMapper.insert(negativeComment); + // 测试 visible 不匹配 + productCommentMapper.insert(cloneIgnoreId(mediocreComment, o -> o.setVisible(Boolean.FALSE))); + // 测试 spuId 不匹配 + productCommentMapper.insert(cloneIgnoreId(mediocreComment, o -> o.setSpuId(2L))); + + // 调用 + 断言:全部可见评价 + PageResult allResult = productCommentService.getCommentPage( + new AppCommentPageReqVO().setSpuId(1L), Boolean.TRUE); + assertEquals(3, allResult.getTotal()); + // 调用 + 断言:好评 + PageResult goodResult = productCommentService.getCommentPage( + new AppCommentPageReqVO().setSpuId(1L).setType(AppCommentPageReqVO.GOOD_COMMENT), Boolean.TRUE); + assertEquals(1, goodResult.getTotal()); + assertPojoEquals(goodComment, goodResult.getList().get(0)); + // 调用 + 断言:中评 + PageResult mediocreResult = productCommentService.getCommentPage( + new AppCommentPageReqVO().setSpuId(1L).setType(AppCommentPageReqVO.MEDIOCRE_COMMENT), Boolean.TRUE); + assertEquals(1, mediocreResult.getTotal()); + assertPojoEquals(mediocreComment, mediocreResult.getList().get(0)); + // 调用 + 断言:差评 + PageResult negativeResult = productCommentService.getCommentPage( + new AppCommentPageReqVO().setSpuId(1L).setType(AppCommentPageReqVO.NEGATIVE_COMMENT), Boolean.TRUE); + assertEquals(1, negativeResult.getTotal()); + assertPojoEquals(negativeComment, negativeResult.getList().get(0)); + // 调用 + 断言:不过滤可见性时,包含隐藏的中评 + PageResult mediocreAllResult = productCommentService.getCommentPage( + new AppCommentPageReqVO().setSpuId(1L).setType(AppCommentPageReqVO.MEDIOCRE_COMMENT), null); + assertEquals(2, mediocreAllResult.getTotal()); + } - // 测试获取所有商品分页评论数据 - PageResult result1 = productCommentService.getCommentPage(new AppCommentPageReqVO(), Boolean.TRUE); - assertEquals(7, result1.getTotal()); + // ========== 更新评价 ========== - // 测试获取所有商品分页中评数据 - PageResult result2 = productCommentService.getCommentPage(new AppCommentPageReqVO().setType(AppCommentPageReqVO.MEDIOCRE_COMMENT), Boolean.TRUE); - assertEquals(2, result2.getTotal()); + @Test + public void testUpdateCommentVisible_success() { + // mock 数据 + ProductCommentDO dbComment = randomCommentDO(o -> o.setVisible(Boolean.TRUE)); + productCommentMapper.insert(dbComment); + // 准备参数 + ProductCommentUpdateVisibleReqVO reqVO = new ProductCommentUpdateVisibleReqVO(); + reqVO.setId(dbComment.getId()); + reqVO.setVisible(Boolean.FALSE); - // 测试获取指定 spuId 商品分页中评数据 - PageResult result3 = productCommentService.getCommentPage(new AppCommentPageReqVO().setSpuId(spuId).setType(AppCommentPageReqVO.MEDIOCRE_COMMENT), Boolean.TRUE); - assertEquals(2, result3.getTotal()); + // 调用 + productCommentService.updateCommentVisible(reqVO); + // 断言 + ProductCommentDO comment = productCommentMapper.selectById(dbComment.getId()); + assertFalse(comment.getVisible()); + assertPojoEquals(dbComment, comment, "visible", "updater", "updateTime"); + } - // 测试分页 tab count - //AppCommentStatisticsRespVO tabsCount = productCommentService.getCommentStatistics(spuId, Boolean.TRUE); - //assertEquals(4, tabsCount.getGoodCount()); - //assertEquals(2, tabsCount.getMediocreCount()); - //assertEquals(0, tabsCount.getNegativeCount()); + @Test + public void testUpdateCommentVisible_notExists() { + // 准备参数 + ProductCommentUpdateVisibleReqVO reqVO = new ProductCommentUpdateVisibleReqVO(); + reqVO.setId(randomLongId()); + reqVO.setVisible(Boolean.FALSE); + // 调用,并断言异常 + assertServiceException(() -> productCommentService.updateCommentVisible(reqVO), COMMENT_NOT_EXISTS); } @Test - public void testUpdateCommentVisible_success() { - // mock 测试 - ProductCommentDO productComment = randomPojo(ProductCommentDO.class, o -> { - o.setVisible(Boolean.TRUE); - }); - productCommentMapper.insert(productComment); + public void testReplyComment_success() { + // mock 数据 + ProductCommentDO dbComment = randomCommentDO(o -> o.setReplyStatus(Boolean.FALSE) + .setReplyUserId(null).setReplyContent(null).setReplyTime(null)); + productCommentMapper.insert(dbComment); + // 准备参数 + ProductCommentReplyReqVO reqVO = new ProductCommentReplyReqVO(); + reqVO.setId(dbComment.getId()); + reqVO.setReplyContent("测试"); + Long userId = randomLongId(); - Long productCommentId = productComment.getId(); + // 调用 + productCommentService.replyComment(reqVO, userId); + // 断言 + ProductCommentDO comment = productCommentMapper.selectById(dbComment.getId()); + assertTrue(comment.getReplyStatus()); + assertEquals(userId, comment.getReplyUserId()); + assertEquals("测试", comment.getReplyContent()); + assertNotNull(comment.getReplyTime()); + } - ProductCommentUpdateVisibleReqVO updateReqVO = new ProductCommentUpdateVisibleReqVO(); - updateReqVO.setId(productCommentId); - updateReqVO.setVisible(Boolean.FALSE); - productCommentService.updateCommentVisible(updateReqVO); + @Test + public void testReplyComment_notExists() { + // 准备参数 + ProductCommentReplyReqVO reqVO = new ProductCommentReplyReqVO(); + reqVO.setId(randomLongId()); + reqVO.setReplyContent("测试"); - ProductCommentDO productCommentDO = productCommentMapper.selectById(productCommentId); - assertFalse(productCommentDO.getVisible()); + // 调用,并断言异常 + assertServiceException(() -> productCommentService.replyComment(reqVO, randomLongId()), COMMENT_NOT_EXISTS); } + // ========== 随机对象 ========== - @Test - public void testCommentReply_success() { - // mock 测试 - ProductCommentDO productComment = randomPojo(ProductCommentDO.class); - productCommentMapper.insert(productComment); - - Long productCommentId = productComment.getId(); + private ProductSkuDO mockSku(Long skuId) { + ProductSkuDO sku = randomPojo(ProductSkuDO.class, o -> o.setId(skuId) + .setProperties(singletonList(new ProductSkuDO.Property(1L, "颜色", 2L, "红色")))); + when(productSkuService.getSku(eq(skuId), eq(true))).thenReturn(sku); + return sku; + } - ProductCommentReplyReqVO replyVO = new ProductCommentReplyReqVO(); - replyVO.setId(productCommentId); - replyVO.setReplyContent("测试"); - productCommentService.replyComment(replyVO, 1L); + private ProductSpuDO mockSpu(Long spuId) { + ProductSpuDO spu = randomPojo(ProductSpuDO.class, o -> o.setId(spuId)); + when(productSpuService.getSpu(eq(spuId), eq(true))).thenReturn(spu); + return spu; + } - ProductCommentDO productCommentDO = productCommentMapper.selectById(productCommentId); - assertEquals("测试", productCommentDO.getReplyContent()); + @SafeVarargs + private static ProductCommentDO randomCommentDO(Consumer... consumers) { + Consumer consumer = (o) -> { + o.setScores(randomEle(ProductCommentScoresEnum.values()).getScores()); // 保证 scores 的范围 + o.setDescriptionScores(randomEle(ProductCommentScoresEnum.values()).getScores()); + o.setBenefitScores(randomEle(ProductCommentScoresEnum.values()).getScores()); + o.setSkuProperties(singletonList(new ProductSkuDO.Property(1L, "颜色", 2L, "红色"))); + }; + return randomPojo(ProductCommentDO.class, ArrayUtils.append(consumer, consumers)); } } diff --git a/yudao-module-mall/yudao-module-product/src/test/resources/sql/create_tables.sql b/yudao-module-mall/yudao-module-product/src/test/resources/sql/create_tables.sql index f0f0c70..94aaf78 100644 --- a/yudao-module-mall/yudao-module-product/src/test/resources/sql/create_tables.sql +++ b/yudao-module-mall/yudao-module-product/src/test/resources/sql/create_tables.sql @@ -126,32 +126,34 @@ CREATE TABLE IF NOT EXISTS `product_property_value` ( PRIMARY KEY("id") ) COMMENT '规格值'; -DROP TABLE IF EXISTS `product_comment` ( - `id` bigint NOT NULL AUTO_INCREMENT COMMENT '评论编号,主键自增', +CREATE TABLE IF NOT EXISTS `product_comment` ( + `id` bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY, `user_id` bigint DEFAULT NULL COMMENT '评价人的用户编号关联 MemberUserDO 的 id 编号', `user_nickname` varchar(255) DEFAULT NULL COMMENT '评价人名称', - `user_avatar` varchar(1024) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '评价人头像', - `anonymous` bit(1) DEFAULT NULL COMMENT '是否匿名', + `user_avatar` varchar(1024) DEFAULT NULL COMMENT '评价人头像', + `anonymous` bit DEFAULT NULL COMMENT '是否匿名', `order_id` bigint DEFAULT NULL COMMENT '交易订单编号关联 TradeOrderDO 的 id 编号', `order_item_id` bigint DEFAULT NULL COMMENT '交易订单项编号关联 TradeOrderItemDO 的 id 编号', `spu_id` bigint DEFAULT NULL COMMENT '商品 SPU 编号关联 ProductSpuDO 的 id', `spu_name` varchar(255) DEFAULT NULL COMMENT '商品 SPU 名称', `sku_id` bigint DEFAULT NULL COMMENT '商品 SKU 编号关联 ProductSkuDO 的 id 编号', - `visible` bit(1) DEFAULT NULL COMMENT '是否可见true:显示false:隐藏', + `sku_pic_url` varchar(256) DEFAULT NULL COMMENT '商品 SKU 图片地址', + `sku_properties` varchar(512) DEFAULT NULL COMMENT '属性数组,JSON 格式', + `visible` bit DEFAULT NULL COMMENT '是否可见true:显示false:隐藏', `scores` tinyint DEFAULT NULL COMMENT '评分星级1-5分', `description_scores` tinyint DEFAULT NULL COMMENT '描述星级1-5 星', `benefit_scores` tinyint DEFAULT NULL COMMENT '服务星级1-5 星', - `content` varchar(1024) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '评论内容', + `content` varchar(1024) DEFAULT NULL COMMENT '评论内容', `pic_urls` varchar(4096) DEFAULT NULL COMMENT '评论图片地址数组', - `reply_status` bit(1) DEFAULT NULL COMMENT '商家是否回复', + `reply_status` bit DEFAULT NULL COMMENT '商家是否回复', `reply_user_id` bigint DEFAULT NULL COMMENT '回复管理员编号关联 AdminUserDO 的 id 编号', - `reply_content` varchar(1024) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '商家回复内容', - `reply_time` datetime DEFAULT NULL COMMENT '商家回复时间', - `creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT '创建者', - `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', - `updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT '更新者', - `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', - `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', - `tenant_id` bigint NOT NULL DEFAULT '0' COMMENT '租户编号', - PRIMARY KEY (`id`) USING BTREE -) ENGINE = InnoDB AUTO_INCREMENT = 26 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_bin COMMENT = '商品评论'; \ No newline at end of file + `reply_content` varchar(1024) DEFAULT NULL COMMENT '商家回复内容', + `reply_time` timestamp DEFAULT NULL COMMENT '商家回复时间', + "creator" varchar(64) DEFAULT '', + "create_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updater" varchar(64) DEFAULT '', + "update_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + "deleted" bit NOT NULL DEFAULT FALSE, + "tenant_id" bigint not null default '0', + PRIMARY KEY("id") +) COMMENT '商品评论'; \ No newline at end of file -- libgit2 0.21.4