|
|
@@ -0,0 +1,288 @@
|
|
|
+package cn.iocoder.yudao.module.mes.service.qc.indicatorresult;
|
|
|
+
|
|
|
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
|
|
+import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
|
|
|
+import cn.iocoder.yudao.module.mes.controller.admin.qc.indicatorresult.vo.MesQcIndicatorResultPageReqVO;
|
|
|
+import cn.iocoder.yudao.module.mes.controller.admin.qc.indicatorresult.vo.MesQcIndicatorResultSaveReqVO;
|
|
|
+import cn.iocoder.yudao.module.mes.dal.dataobject.qc.indicator.MesQcIndicatorDO;
|
|
|
+import cn.iocoder.yudao.module.mes.dal.dataobject.qc.indicatorresult.MesQcIndicatorResultDO;
|
|
|
+import cn.iocoder.yudao.module.mes.dal.dataobject.qc.iqc.MesQcIqcDO;
|
|
|
+import cn.iocoder.yudao.module.mes.dal.mysql.qc.indicatorresult.MesQcIndicatorResultMapper;
|
|
|
+import cn.iocoder.yudao.module.mes.enums.qc.MesQcResultValueTypeEnum;
|
|
|
+import cn.iocoder.yudao.module.mes.enums.qc.MesQcTypeEnum;
|
|
|
+import cn.iocoder.yudao.module.mes.service.qc.indicator.MesQcIndicatorService;
|
|
|
+import cn.iocoder.yudao.module.mes.service.qc.ipqc.MesQcIpqcService;
|
|
|
+import cn.iocoder.yudao.module.mes.service.qc.iqc.MesQcIqcService;
|
|
|
+import cn.iocoder.yudao.module.mes.service.qc.oqc.MesQcOqcService;
|
|
|
+import cn.iocoder.yudao.module.mes.service.qc.rqc.MesQcRqcService;
|
|
|
+import cn.iocoder.yudao.module.system.api.dict.DictDataApi;
|
|
|
+import org.junit.jupiter.api.Test;
|
|
|
+import org.springframework.context.annotation.Import;
|
|
|
+import org.springframework.test.context.bean.override.mockito.MockitoBean;
|
|
|
+
|
|
|
+import jakarta.annotation.Resource;
|
|
|
+import java.util.List;
|
|
|
+import java.util.Map;
|
|
|
+
|
|
|
+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.assertServiceException;
|
|
|
+import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomLongId;
|
|
|
+import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo;
|
|
|
+import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.*;
|
|
|
+import static org.junit.jupiter.api.Assertions.*;
|
|
|
+import static org.mockito.ArgumentMatchers.*;
|
|
|
+import static org.mockito.Mockito.*;
|
|
|
+
|
|
|
+/**
|
|
|
+ * {@link MesQcIndicatorResultServiceImpl} 的单元测试
|
|
|
+ *
|
|
|
+ * @author 芋道源码
|
|
|
+ */
|
|
|
+@Import(MesQcIndicatorResultServiceImpl.class)
|
|
|
+public class MesQcIndicatorResultServiceImplTest extends BaseDbUnitTest {
|
|
|
+
|
|
|
+ @Resource
|
|
|
+ private MesQcIndicatorResultServiceImpl indicatorResultService;
|
|
|
+
|
|
|
+ @Resource
|
|
|
+ private MesQcIndicatorResultMapper resultMapper;
|
|
|
+
|
|
|
+ @MockitoBean
|
|
|
+ private MesQcIndicatorResultDetailService resultDetailService;
|
|
|
+ @MockitoBean
|
|
|
+ private MesQcIndicatorService indicatorService;
|
|
|
+ @MockitoBean
|
|
|
+ private MesQcIqcService iqcService;
|
|
|
+ @MockitoBean
|
|
|
+ private MesQcIpqcService ipqcService;
|
|
|
+ @MockitoBean
|
|
|
+ private MesQcOqcService oqcService;
|
|
|
+ @MockitoBean
|
|
|
+ private MesQcRqcService rqcService;
|
|
|
+ @MockitoBean
|
|
|
+ private DictDataApi dictDataApi;
|
|
|
+
|
|
|
+ @Test
|
|
|
+ public void testCreateIndicatorResult_success() {
|
|
|
+ // 准备参数
|
|
|
+ MesQcIndicatorResultSaveReqVO reqVO = buildReqVO("plain text value", MesQcResultValueTypeEnum.TEXT.getType());
|
|
|
+ // mock 方法
|
|
|
+ mockIqcAndIndicator(reqVO, MesQcResultValueTypeEnum.TEXT.getType());
|
|
|
+
|
|
|
+ // 调用
|
|
|
+ Long resultId = indicatorResultService.createIndicatorResult(reqVO);
|
|
|
+
|
|
|
+ // 断言
|
|
|
+ assertNotNull(resultId);
|
|
|
+ MesQcIndicatorResultDO dbResult = resultMapper.selectById(resultId);
|
|
|
+ assertNotNull(dbResult);
|
|
|
+ assertEquals(reqVO.getCode(), dbResult.getCode());
|
|
|
+ assertEquals(reqVO.getQcId(), dbResult.getQcId());
|
|
|
+ assertEquals(reqVO.getQcType(), dbResult.getQcType());
|
|
|
+ assertEquals(100L, dbResult.getItemId()); // 从 mock IQC 获取
|
|
|
+ verify(resultDetailService).createDetailList(anyList());
|
|
|
+ }
|
|
|
+
|
|
|
+ @Test
|
|
|
+ public void testCreateIndicatorResult_fileValueInvalid() {
|
|
|
+ // 准备参数
|
|
|
+ MesQcIndicatorResultSaveReqVO reqVO = buildReqVO("not-a-url", MesQcResultValueTypeEnum.FILE.getType());
|
|
|
+ // mock 方法
|
|
|
+ mockIqcAndIndicator(reqVO, MesQcResultValueTypeEnum.FILE.getType());
|
|
|
+
|
|
|
+ // 调用,并断言异常
|
|
|
+ assertServiceException(() -> indicatorResultService.createIndicatorResult(reqVO),
|
|
|
+ QC_RESULT_VALUE_FORMAT_INVALID, "检测项[检测项A]要求文件 URL,实际值=not-a-url");
|
|
|
+
|
|
|
+ // 断言:未入库
|
|
|
+ assertEquals(0, resultMapper.selectCount());
|
|
|
+ verify(resultDetailService, never()).createDetailList(anyList());
|
|
|
+ }
|
|
|
+
|
|
|
+ @Test
|
|
|
+ public void testUpdateIndicatorResult_success() {
|
|
|
+ // mock 数据
|
|
|
+ MesQcIndicatorResultDO dbResult = randomPojo(MesQcIndicatorResultDO.class, o -> {
|
|
|
+ o.setQcType(MesQcTypeEnum.IQC.getType());
|
|
|
+ });
|
|
|
+ resultMapper.insert(dbResult);
|
|
|
+ // 准备参数
|
|
|
+ MesQcIndicatorResultSaveReqVO reqVO = buildReqVO("updated text", MesQcResultValueTypeEnum.TEXT.getType());
|
|
|
+ reqVO.setId(dbResult.getId());
|
|
|
+ // mock 方法
|
|
|
+ MesQcIndicatorDO indicator = new MesQcIndicatorDO();
|
|
|
+ indicator.setId(reqVO.getItems().get(0).getIndicatorId());
|
|
|
+ indicator.setName("检测项A");
|
|
|
+ indicator.setResultType(MesQcResultValueTypeEnum.TEXT.getType());
|
|
|
+ when(indicatorService.validateIndicatorListExists(anySet()))
|
|
|
+ .thenReturn(Map.of(indicator.getId(), indicator));
|
|
|
+
|
|
|
+ // 调用
|
|
|
+ indicatorResultService.updateIndicatorResult(reqVO);
|
|
|
+
|
|
|
+ // 断言
|
|
|
+ MesQcIndicatorResultDO updatedResult = resultMapper.selectById(dbResult.getId());
|
|
|
+ assertEquals(reqVO.getCode(), updatedResult.getCode());
|
|
|
+ // qcId/qcType/itemId 不允许改挂,应保持原值
|
|
|
+ assertEquals(dbResult.getQcId(), updatedResult.getQcId());
|
|
|
+ assertEquals(dbResult.getQcType(), updatedResult.getQcType());
|
|
|
+ assertEquals(dbResult.getItemId(), updatedResult.getItemId());
|
|
|
+ verify(resultDetailService).createOrUpdateDetailList(anyList());
|
|
|
+ }
|
|
|
+
|
|
|
+ @Test
|
|
|
+ public void testUpdateIndicatorResult_notExists() {
|
|
|
+ // 准备参数
|
|
|
+ MesQcIndicatorResultSaveReqVO reqVO = buildReqVO("text", MesQcResultValueTypeEnum.TEXT.getType());
|
|
|
+ reqVO.setId(randomLongId());
|
|
|
+
|
|
|
+ // 调用,并断言异常
|
|
|
+ assertServiceException(() -> indicatorResultService.updateIndicatorResult(reqVO),
|
|
|
+ QC_RESULT_NOT_EXISTS);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Test
|
|
|
+ public void testDeleteIndicatorResult_success() {
|
|
|
+ // mock 数据
|
|
|
+ MesQcIndicatorResultDO dbResult = randomPojo(MesQcIndicatorResultDO.class);
|
|
|
+ resultMapper.insert(dbResult);
|
|
|
+
|
|
|
+ // 调用
|
|
|
+ indicatorResultService.deleteIndicatorResult(dbResult.getId());
|
|
|
+
|
|
|
+ // 断言
|
|
|
+ assertNull(resultMapper.selectById(dbResult.getId()));
|
|
|
+ verify(resultDetailService).deleteDetailByResultId(dbResult.getId());
|
|
|
+ }
|
|
|
+
|
|
|
+ @Test
|
|
|
+ public void testDeleteIndicatorResult_notExists() {
|
|
|
+ // 调用,并断言异常
|
|
|
+ assertServiceException(() -> indicatorResultService.deleteIndicatorResult(randomLongId()),
|
|
|
+ QC_RESULT_NOT_EXISTS);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Test
|
|
|
+ public void testGetIndicatorResult() {
|
|
|
+ // mock 数据
|
|
|
+ MesQcIndicatorResultDO dbResult = randomPojo(MesQcIndicatorResultDO.class);
|
|
|
+ resultMapper.insert(dbResult);
|
|
|
+
|
|
|
+ // 调用
|
|
|
+ MesQcIndicatorResultDO result = indicatorResultService.getIndicatorResult(dbResult.getId());
|
|
|
+
|
|
|
+ // 断言
|
|
|
+ assertPojoEquals(dbResult, result);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Test
|
|
|
+ public void testGetIndicatorResultPage() {
|
|
|
+ // mock 数据
|
|
|
+ MesQcIndicatorResultDO dbResult = randomPojo(MesQcIndicatorResultDO.class, o -> {
|
|
|
+ o.setQcId(1L);
|
|
|
+ o.setQcType(MesQcTypeEnum.IQC.getType());
|
|
|
+ o.setCode("SPL-001");
|
|
|
+ o.setItemId(100L);
|
|
|
+ });
|
|
|
+ resultMapper.insert(dbResult);
|
|
|
+ // 测试 qcId 不匹配
|
|
|
+ resultMapper.insert(cloneIgnoreId(dbResult, o -> o.setQcId(2L)));
|
|
|
+ // 测试 qcType 不匹配
|
|
|
+ resultMapper.insert(cloneIgnoreId(dbResult, o -> o.setQcType(MesQcTypeEnum.IPQC.getType())));
|
|
|
+ // 测试 code 不匹配
|
|
|
+ resultMapper.insert(cloneIgnoreId(dbResult, o -> o.setCode("SPL-999")));
|
|
|
+ // 测试 itemId 不匹配
|
|
|
+ resultMapper.insert(cloneIgnoreId(dbResult, o -> o.setItemId(999L)));
|
|
|
+ // 准备参数
|
|
|
+ MesQcIndicatorResultPageReqVO pageReqVO = new MesQcIndicatorResultPageReqVO();
|
|
|
+ pageReqVO.setQcId(1L);
|
|
|
+ pageReqVO.setQcType(MesQcTypeEnum.IQC.getType());
|
|
|
+ pageReqVO.setCode("SPL-001");
|
|
|
+ pageReqVO.setItemId(100L);
|
|
|
+
|
|
|
+ // 调用
|
|
|
+ PageResult<MesQcIndicatorResultDO> pageResult = indicatorResultService.getIndicatorResultPage(pageReqVO);
|
|
|
+
|
|
|
+ // 断言
|
|
|
+ assertEquals(1, pageResult.getTotal());
|
|
|
+ assertEquals(1, pageResult.getList().size());
|
|
|
+ assertPojoEquals(dbResult, pageResult.getList().get(0));
|
|
|
+ }
|
|
|
+
|
|
|
+ @Test
|
|
|
+ public void testGetIndicatorResultCountByQcIdAndType() {
|
|
|
+ // mock 数据
|
|
|
+ MesQcIndicatorResultDO result1 = randomPojo(MesQcIndicatorResultDO.class, o -> {
|
|
|
+ o.setQcId(1L);
|
|
|
+ o.setQcType(MesQcTypeEnum.IQC.getType());
|
|
|
+ });
|
|
|
+ resultMapper.insert(result1);
|
|
|
+ MesQcIndicatorResultDO result2 = randomPojo(MesQcIndicatorResultDO.class, o -> {
|
|
|
+ o.setQcId(1L);
|
|
|
+ o.setQcType(MesQcTypeEnum.IQC.getType());
|
|
|
+ });
|
|
|
+ resultMapper.insert(result2);
|
|
|
+ // 不匹配
|
|
|
+ resultMapper.insert(randomPojo(MesQcIndicatorResultDO.class, o -> {
|
|
|
+ o.setQcId(2L);
|
|
|
+ o.setQcType(MesQcTypeEnum.IPQC.getType());
|
|
|
+ }));
|
|
|
+
|
|
|
+ // 调用
|
|
|
+ Long count = indicatorResultService.getIndicatorResultCountByQcIdAndType(1L, MesQcTypeEnum.IQC.getType());
|
|
|
+
|
|
|
+ // 断言
|
|
|
+ assertEquals(2L, count);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Test
|
|
|
+ public void testValidateIndicatorResultExistsByQcIdAndType_success() {
|
|
|
+ // mock 数据
|
|
|
+ resultMapper.insert(randomPojo(MesQcIndicatorResultDO.class, o -> {
|
|
|
+ o.setQcId(1L);
|
|
|
+ o.setQcType(MesQcTypeEnum.IQC.getType());
|
|
|
+ }));
|
|
|
+
|
|
|
+ // 调用(不抛异常即通过)
|
|
|
+ indicatorResultService.validateIndicatorResultExistsByQcIdAndType(1L, MesQcTypeEnum.IQC.getType());
|
|
|
+ }
|
|
|
+
|
|
|
+ @Test
|
|
|
+ public void testValidateIndicatorResultExistsByQcIdAndType_notExists() {
|
|
|
+ // 调用,并断言异常
|
|
|
+ assertServiceException(
|
|
|
+ () -> indicatorResultService.validateIndicatorResultExistsByQcIdAndType(randomLongId(), MesQcTypeEnum.IQC.getType()),
|
|
|
+ QC_FINISH_INDICATOR_RESULT_REQUIRED);
|
|
|
+ }
|
|
|
+
|
|
|
+ // ==================== 辅助方法 ====================
|
|
|
+
|
|
|
+ private void mockIqcAndIndicator(MesQcIndicatorResultSaveReqVO reqVO, Integer resultType) {
|
|
|
+ MesQcIqcDO iqc = new MesQcIqcDO();
|
|
|
+ iqc.setId(reqVO.getQcId());
|
|
|
+ iqc.setItemId(100L);
|
|
|
+ when(iqcService.validateIqcExists(reqVO.getQcId())).thenReturn(iqc);
|
|
|
+
|
|
|
+ MesQcIndicatorDO indicator = new MesQcIndicatorDO();
|
|
|
+ indicator.setId(reqVO.getItems().get(0).getIndicatorId());
|
|
|
+ indicator.setName("检测项A");
|
|
|
+ indicator.setResultType(resultType);
|
|
|
+ when(indicatorService.validateIndicatorListExists(anySet()))
|
|
|
+ .thenReturn(Map.of(indicator.getId(), indicator));
|
|
|
+ }
|
|
|
+
|
|
|
+ private MesQcIndicatorResultSaveReqVO buildReqVO(String value, Integer resultType) {
|
|
|
+ MesQcIndicatorResultSaveReqVO.Item item = new MesQcIndicatorResultSaveReqVO.Item();
|
|
|
+ item.setIndicatorId(10L);
|
|
|
+ item.setValue(value);
|
|
|
+
|
|
|
+ MesQcIndicatorResultSaveReqVO reqVO = new MesQcIndicatorResultSaveReqVO();
|
|
|
+ reqVO.setCode("SPL-001");
|
|
|
+ reqVO.setQcId(1L);
|
|
|
+ reqVO.setQcType(MesQcTypeEnum.IQC.getType());
|
|
|
+ reqVO.setItems(List.of(item));
|
|
|
+ return reqVO;
|
|
|
+ }
|
|
|
+
|
|
|
+}
|