mirror of
http://192.168.1.205:9980/cf_devdept2/cf_imes_server.git
synced 2026-08-14 21:52:07 +08:00
产品明细单元测试完善、无用字段移除
This commit is contained in:
-20
@@ -1,7 +1,6 @@
|
|||||||
package com.cf.imes.module.system.controller.admin.funds.products.vo.productDetails;
|
package com.cf.imes.module.system.controller.admin.funds.products.vo.productDetails;
|
||||||
|
|
||||||
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
|
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
|
||||||
import com.cf.imes.module.system.validation.products.ProductType;
|
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
@@ -20,28 +19,12 @@ public class ProductDetailsRespVO {
|
|||||||
@Schema(description = "产品ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
@Schema(description = "产品ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||||
private Long productId;
|
private Long productId;
|
||||||
|
|
||||||
@Schema(description = "购买方式", requiredMode = Schema.RequiredMode.REQUIRED, example = "购买方式:0时长;1产量")
|
|
||||||
@ProductType
|
|
||||||
private Integer purchaseType;
|
|
||||||
|
|
||||||
@Schema(description = "购买时长", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
@Schema(description = "购买时长", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||||
private Integer duration;
|
private Integer duration;
|
||||||
|
|
||||||
@Schema(description = "产品时长单位,0:年、1:月", example = "1")
|
@Schema(description = "产品时长单位,0:年、1:月", example = "1")
|
||||||
private Integer durationUnit;
|
private Integer durationUnit;
|
||||||
|
|
||||||
@Schema(description = "正常产量", requiredMode = Schema.RequiredMode.REQUIRED, example = "")
|
|
||||||
private BigDecimal output;
|
|
||||||
|
|
||||||
@Schema(description = "赠送时长", example = "1")
|
|
||||||
private Integer giftDuration;
|
|
||||||
|
|
||||||
@Schema(description = "赠送时长单位,0:年、1:月", example = "1")
|
|
||||||
private Integer giftDurationUnit;
|
|
||||||
|
|
||||||
@Schema(description = "赠送产量", requiredMode = Schema.RequiredMode.REQUIRED, example = "")
|
|
||||||
private BigDecimal giftOutput;
|
|
||||||
|
|
||||||
@Schema(description = "产品原价", requiredMode = Schema.RequiredMode.REQUIRED, example = "100")
|
@Schema(description = "产品原价", requiredMode = Schema.RequiredMode.REQUIRED, example = "100")
|
||||||
private BigDecimal originalPrice;
|
private BigDecimal originalPrice;
|
||||||
|
|
||||||
@@ -51,9 +34,6 @@ public class ProductDetailsRespVO {
|
|||||||
@Schema(description = "产品现价", requiredMode = Schema.RequiredMode.REQUIRED, example = "80")
|
@Schema(description = "产品现价", requiredMode = Schema.RequiredMode.REQUIRED, example = "80")
|
||||||
private BigDecimal currentPrice;
|
private BigDecimal currentPrice;
|
||||||
|
|
||||||
@Schema(description = "是否特惠", requiredMode = Schema.RequiredMode.REQUIRED, example = "是")
|
|
||||||
private Boolean isDiscounted;
|
|
||||||
|
|
||||||
@Schema(description = "操作时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
@Schema(description = "操作时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
private LocalDateTime updateTime;
|
private LocalDateTime updateTime;
|
||||||
|
|
||||||
|
|||||||
-7
@@ -1,6 +1,5 @@
|
|||||||
package com.cf.imes.module.system.controller.admin.funds.products.vo.productDetails;
|
package com.cf.imes.module.system.controller.admin.funds.products.vo.productDetails;
|
||||||
|
|
||||||
import com.cf.imes.module.system.enums.products.ProductsPurchaseTypeEnum;
|
|
||||||
import com.cf.imes.module.system.validation.products.ProductDurationUnitValid;
|
import com.cf.imes.module.system.validation.products.ProductDurationUnitValid;
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
import jakarta.validation.constraints.DecimalMax;
|
import jakarta.validation.constraints.DecimalMax;
|
||||||
@@ -23,9 +22,6 @@ public class ProductDetailsSaveReqVO {
|
|||||||
@NotNull(message = "产品名称不能为空")
|
@NotNull(message = "产品名称不能为空")
|
||||||
private Long productId;
|
private Long productId;
|
||||||
|
|
||||||
@Schema(description = "购买方式", requiredMode = Schema.RequiredMode.REQUIRED, example = "0")
|
|
||||||
private Integer purchaseType = ProductsPurchaseTypeEnum.DURATION.getStatus();
|
|
||||||
|
|
||||||
@Schema(description = "产品时长,格式:时长值", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
@Schema(description = "产品时长,格式:时长值", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||||
@Min(value = 1, message = "产品时长必须大于0")
|
@Min(value = 1, message = "产品时长必须大于0")
|
||||||
@NotNull(message = "产品时长不能为空")
|
@NotNull(message = "产品时长不能为空")
|
||||||
@@ -43,7 +39,4 @@ public class ProductDetailsSaveReqVO {
|
|||||||
@NotNull(message = "折扣不能为空")
|
@NotNull(message = "折扣不能为空")
|
||||||
private BigDecimal discount;
|
private BigDecimal discount;
|
||||||
|
|
||||||
@Schema(description = "是否特惠", requiredMode = Schema.RequiredMode.REQUIRED, example = "true")
|
|
||||||
private Boolean isDiscounted;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+168
@@ -0,0 +1,168 @@
|
|||||||
|
package com.cf.imes.module.system.controller.admin.funds.products;
|
||||||
|
|
||||||
|
import com.cf.imes.framework.common.pojo.PageResult;
|
||||||
|
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.ProductDetailsRespVO;
|
||||||
|
import com.cf.imes.module.system.controller.admin.funds.products.vo.productDetails.ProductDetailsSaveReqVO;
|
||||||
|
import com.cf.imes.module.system.dal.dataobject.funds.products.ProductsDetailDO;
|
||||||
|
import com.cf.imes.module.system.enums.pay.ProductDurationUnitEnum;
|
||||||
|
import com.cf.imes.module.system.service.funds.products.ProductsDetailService;
|
||||||
|
import com.cf.imes.module.system.service.funds.purchase.PurchaseService;
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration;
|
||||||
|
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
|
||||||
|
import org.springframework.http.MediaType;
|
||||||
|
import org.springframework.test.context.bean.override.mockito.MockitoBean;
|
||||||
|
import org.springframework.test.web.servlet.MockMvc;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
|
import static org.mockito.ArgumentMatchers.anyLong;
|
||||||
|
import static org.mockito.Mockito.doNothing;
|
||||||
|
import static org.mockito.Mockito.times;
|
||||||
|
import static org.mockito.Mockito.verify;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete;
|
||||||
|
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
||||||
|
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
|
||||||
|
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put;
|
||||||
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
||||||
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Gqr
|
||||||
|
* @since 2025/10/24 9:41
|
||||||
|
*/
|
||||||
|
@WebMvcTest(controllers = ProductsDetailController.class, excludeAutoConfiguration = SecurityAutoConfiguration.class)
|
||||||
|
public class ProductsDetailControllerTest {
|
||||||
|
@Autowired
|
||||||
|
private MockMvc mockMvc;
|
||||||
|
|
||||||
|
@MockitoBean
|
||||||
|
private ProductsDetailService productsDetailService;
|
||||||
|
|
||||||
|
@MockitoBean
|
||||||
|
private PurchaseService purchaseService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ObjectMapper objectMapper;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testCreateProductDetails() throws Exception {
|
||||||
|
ProductDetailsSaveReqVO vo = new ProductDetailsSaveReqVO();
|
||||||
|
vo.setProductId(123L);
|
||||||
|
vo.setDuration(1);
|
||||||
|
vo.setDurationUnit(ProductDurationUnitEnum.YEAR.getCode());
|
||||||
|
vo.setDiscount(BigDecimal.valueOf(100));
|
||||||
|
|
||||||
|
// mock Service 返回
|
||||||
|
when(productsDetailService.create(any())).thenReturn(100L);
|
||||||
|
|
||||||
|
mockMvc.perform(put("/system/product-details")
|
||||||
|
.contentType(MediaType.APPLICATION_JSON)
|
||||||
|
.content(objectMapper.writeValueAsString(vo)))
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
.andExpect(jsonPath("$.data").value(100));
|
||||||
|
|
||||||
|
// 验证 Service 调用
|
||||||
|
verify(productsDetailService, times(1)).create(any());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testUpdateProductDetails() throws Exception {
|
||||||
|
ProductDetailsSaveReqVO vo = new ProductDetailsSaveReqVO();
|
||||||
|
vo.setId(1L);
|
||||||
|
vo.setProductId(123L);
|
||||||
|
vo.setDuration(2);
|
||||||
|
vo.setDurationUnit(ProductDurationUnitEnum.YEAR.getCode());
|
||||||
|
vo.setDiscount(BigDecimal.valueOf(80));
|
||||||
|
|
||||||
|
// mock Service 方法 void 不做实际处理
|
||||||
|
doNothing().when(productsDetailService).update(any());
|
||||||
|
|
||||||
|
mockMvc.perform(post("/system/product-details")
|
||||||
|
.contentType(MediaType.APPLICATION_JSON)
|
||||||
|
.content(objectMapper.writeValueAsString(vo)))
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
.andExpect(jsonPath("$.data").value(true));
|
||||||
|
|
||||||
|
verify(productsDetailService, times(1)).update(any());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testDeleteProductDetails() throws Exception {
|
||||||
|
Long id = 3L;
|
||||||
|
doNothing().when(productsDetailService).delete(anyLong());
|
||||||
|
|
||||||
|
mockMvc.perform(delete("/system/product-details")
|
||||||
|
.param("id", id.toString()))
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
.andExpect(jsonPath("$.data").value(true));
|
||||||
|
|
||||||
|
verify(productsDetailService, times(1)).delete(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testGetProducts() throws Exception {
|
||||||
|
Long id = 4L;
|
||||||
|
ProductsDetailDO mockProduct = new ProductsDetailDO()
|
||||||
|
.setId(id)
|
||||||
|
.setProductId(123L);
|
||||||
|
when(productsDetailService.get(id)).thenReturn(mockProduct);
|
||||||
|
|
||||||
|
mockMvc.perform(get("/system/product-details/{id}", id))
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
.andExpect(jsonPath("$.data.productId").value(123L));
|
||||||
|
|
||||||
|
verify(productsDetailService, times(1)).get(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testGetProductsPage() throws Exception {
|
||||||
|
ProductDetailsPageReqVO reqVO = new ProductDetailsPageReqVO();
|
||||||
|
PageResult<ProductsDetailDO> mockPage = new PageResult<>();
|
||||||
|
mockPage.setTotal(1L);
|
||||||
|
mockPage.setList(List.of(new ProductsDetailDO().setId(1L).setProductId(123L)));
|
||||||
|
when(productsDetailService.getPage(any())).thenReturn(mockPage);
|
||||||
|
|
||||||
|
mockMvc.perform(get("/system/product-details/page")
|
||||||
|
.contentType(MediaType.APPLICATION_JSON)
|
||||||
|
.content(objectMapper.writeValueAsString(reqVO)))
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
.andExpect(jsonPath("$.data.list[0].productId").value(123L));
|
||||||
|
|
||||||
|
verify(productsDetailService, times(1)).getPage(any());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testGetOrgProductDetailList() throws Exception {
|
||||||
|
// 模拟返回数据
|
||||||
|
ProductDetailsRespVO mockVO = new ProductDetailsRespVO();
|
||||||
|
mockVO.setId(1L);
|
||||||
|
mockVO.setProductId(1001L);
|
||||||
|
List<ProductDetailsRespVO> mockList = List.of(mockVO);
|
||||||
|
|
||||||
|
// Mock Service 层行为
|
||||||
|
when(purchaseService.getOrgProductDetailList(anyLong(), anyLong()))
|
||||||
|
.thenReturn(mockList);
|
||||||
|
|
||||||
|
// 执行请求
|
||||||
|
mockMvc.perform(get("/system/product-details/organ/purchase")
|
||||||
|
.param("organId", "100")
|
||||||
|
.param("productId", "200")
|
||||||
|
.contentType(MediaType.APPLICATION_JSON))
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
.andExpect(jsonPath("$.code").value(0))
|
||||||
|
.andExpect(jsonPath("$.data[0].productId").value(1001))
|
||||||
|
.andExpect(jsonPath("$.data[0].id").value(1L));
|
||||||
|
|
||||||
|
// 验证 Service 是否被正确调用一次
|
||||||
|
verify(purchaseService, times(1)).getOrgProductDetailList(100L, 200L);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user