云
6 天以前 ac2e2b5af3726ee64dc37c3ebf26989a0346f22a
yudao-module-mes/src/test/java/cn/iocoder/yudao/module/mes/service/pro/feedback/MesProFeedbackServiceImplTest.java
@@ -2,20 +2,30 @@
import cn.hutool.core.collection.ListUtil;
import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
import cn.iocoder.yudao.module.mes.controller.admin.pro.feedback.vo.MesProFeedbackApproveReqVO;
import cn.iocoder.yudao.module.mes.dal.dataobject.pro.feedback.MesProFeedbackDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.pro.route.MesProRouteProcessDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.pro.workorder.MesProWorkOrderProcessDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productproduce.MesWmProductProduceDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productproduce.MesWmProductProduceLineDO;
import cn.iocoder.yudao.module.mes.dal.mysql.pro.feedback.MesProFeedbackMapper;
import cn.iocoder.yudao.module.mes.enums.pro.MesProFeedbackStatusEnum;
import cn.iocoder.yudao.module.mes.enums.wm.MesWmQualityStatusEnum;
import cn.iocoder.yudao.module.mes.api.mps.MesProMpsApi;
import cn.iocoder.yudao.module.mes.service.md.autocode.MesMdAutoCodeRecordService;
import cn.iocoder.yudao.module.mes.service.md.workstation.MesMdWorkstationService;
import cn.iocoder.yudao.module.mes.service.mdm.MesMdmItemService;
import cn.iocoder.yudao.module.mes.service.pro.route.MesProRouteProcessService;
import cn.iocoder.yudao.module.mes.service.pro.task.MesProTaskService;
import cn.iocoder.yudao.module.mes.service.pro.workorder.MesProWorkOrderBomService;
import cn.iocoder.yudao.module.mes.service.pro.workorder.MesProWorkOrderProcessService;
import cn.iocoder.yudao.module.mes.service.pro.workorder.MesProWorkOrderService;
import cn.iocoder.yudao.module.mes.service.qc.template.MesQcTemplateItemService;
import cn.iocoder.yudao.module.mes.service.wm.itemconsume.MesWmItemConsumeService;
import cn.iocoder.yudao.module.mes.service.wm.productissue.MesWmProductIssueService;
import cn.iocoder.yudao.module.mes.service.wm.productproduce.MesWmProductProduceLineService;
import cn.iocoder.yudao.module.mes.service.wm.productproduce.MesWmProductProduceService;
import cn.iocoder.yudao.module.mdm.api.item.MdmItemBatchConfigApi;
import jakarta.annotation.Resource;
import org.junit.jupiter.api.Test;
import org.springframework.context.annotation.Import;
@@ -31,7 +41,7 @@
/**
 * {@link MesProFeedbackServiceImpl} 的单元测试
 *
 * @author 芋道源码
 * @author 超级管理员
 */
@Import(MesProFeedbackServiceImpl.class)
public class MesProFeedbackServiceImplTest extends BaseDbUnitTest {
@@ -43,9 +53,15 @@
    private MesProFeedbackMapper feedbackMapper;
    @MockitoBean
    private MesFeedbackParamService feedbackParamService;
    @MockitoBean
    private MesProWorkOrderService workOrderService;
    @MockitoBean
    private MesProRouteProcessService routeProcessService;
    @MockitoBean
    private MesProWorkOrderBomService workOrderBomService;
    @MockitoBean
    private MesProWorkOrderProcessService workOrderProcessService;
    @MockitoBean
    private MesMdWorkstationService workstationService;
    @MockitoBean
@@ -53,9 +69,21 @@
    @MockitoBean
    private MesWmItemConsumeService itemConsumeService;
    @MockitoBean
    private MesWmProductIssueService productIssueService;
    @MockitoBean
    private MesWmProductProduceService productProduceService;
    @MockitoBean
    private MesWmProductProduceLineService produceLineService;
    @MockitoBean
    private MesProMpsApi mpsApi;
    @MockitoBean
    private MesMdAutoCodeRecordService autoCodeRecordService;
    @MockitoBean
    private MesMdmItemService mdmItemService;
    @MockitoBean
    private MdmItemBatchConfigApi itemBatchConfigApi;
    @MockitoBean
    private MesQcTemplateItemService templateItemService;
    @Test
    public void testUpdateProFeedbackWhenIpqcFinish_success_withUnqualified() {
@@ -68,6 +96,7 @@
            o.setTaskId(taskId);
            o.setWorkOrderId(workOrderId);
            o.setFeedbackQuantity(BigDecimal.valueOf(100));
            resetFeedbackQuantities(o);
        });
        feedbackMapper.insert(feedback);
@@ -82,6 +111,7 @@
                .build();
        when(produceLineService.getProductProduceLineListByFeedbackId(feedback.getId()))
                .thenReturn(ListUtil.of(qualifiedLine, unqualifiedLine));
        mockLastProcess(feedback.getProcessId());
        // 调用
        BigDecimal qualifiedQty = BigDecimal.valueOf(80);
@@ -126,6 +156,7 @@
            o.setTaskId(taskId);
            o.setWorkOrderId(workOrderId);
            o.setFeedbackQuantity(BigDecimal.valueOf(50));
            resetFeedbackQuantities(o);
        });
        feedbackMapper.insert(feedback);
@@ -136,6 +167,7 @@
                .build();
        when(produceLineService.getProductProduceLineListByFeedbackId(feedback.getId()))
                .thenReturn(ListUtil.of(qualifiedLine));
        mockLastProcess(feedback.getProcessId());
        // 调用
        feedbackService.updateProFeedbackWhenIpqcFinish(feedback.getId(), randomLongId(),
@@ -222,7 +254,7 @@
        // mock: 产品产出单
        MesWmProductProduceDO produce = randomPojo(MesWmProductProduceDO.class);
        when(productProduceService.generateProductProduce(any(), eq(false))).thenReturn(produce);
        when(productProduceService.generateProductProduce(any(), eq(false), any())).thenReturn(produce);
        // mock: 产出行(用于 updateTaskAndWorkOrderByFeedback)
        MesWmProductProduceLineDO qualifiedLine = MesWmProductProduceLineDO.builder()
@@ -232,7 +264,9 @@
                .thenReturn(ListUtil.of(qualifiedLine));
        // 调用
        boolean result = feedbackService.approveFeedback(feedback.getId());
        MesProFeedbackApproveReqVO reqVO = new MesProFeedbackApproveReqVO();
        reqVO.setId(feedback.getId());
        boolean result = feedbackService.approveFeedback(reqVO);
        // 断言 1:返回 true(已完成)
        assertTrue(result);
@@ -243,7 +277,7 @@
        assertEquals(0, BigDecimal.ZERO.compareTo(updated.getUncheckQuantity()));
        // 断言 3:调用了产出单生成 + 入库 + 任务/工单更新
        verify(productProduceService).generateProductProduce(any(), eq(false));
        verify(productProduceService).generateProductProduce(any(), eq(false), any());
        verify(productProduceService).finishProductProduce(produce.getId());
        verify(taskService).updateProducedQuantity(eq(feedback.getTaskId()),
                any(BigDecimal.class), any(BigDecimal.class), any(BigDecimal.class));
@@ -273,7 +307,9 @@
                .thenReturn(routeProcess);
        // 调用
        boolean result = feedbackService.approveFeedback(feedback.getId());
        MesProFeedbackApproveReqVO reqVO = new MesProFeedbackApproveReqVO();
        reqVO.setId(feedback.getId());
        boolean result = feedbackService.approveFeedback(reqVO);
        // 断言 1:返回 false(待检验)
        assertFalse(result);
@@ -283,7 +319,7 @@
        assertEquals(MesProFeedbackStatusEnum.UNCHECK.getStatus(), updated.getStatus());
        // 断言 3:生成了待检产出单,但没有 finishProductProduce
        verify(productProduceService).generateProductProduce(any(), eq(true));
        verify(productProduceService).generateProductProduce(any(), eq(true), any());
        verify(productProduceService, never()).finishProductProduce(anyLong());
        // 断言 4:没有更新任务/工单数量(等 IPQC 回调)
@@ -313,7 +349,9 @@
                .thenReturn(routeProcess);
        // 调用
        boolean result = feedbackService.approveFeedback(feedback.getId());
        MesProFeedbackApproveReqVO reqVO = new MesProFeedbackApproveReqVO();
        reqVO.setId(feedback.getId());
        boolean result = feedbackService.approveFeedback(reqVO);
        // 断言 1:返回 true(已完成)
        assertTrue(result);
@@ -323,7 +361,7 @@
        assertEquals(MesProFeedbackStatusEnum.FINISHED.getStatus(), updated.getStatus());
        // 断言 3:不生成产出单,不更新任务/工单
        verify(productProduceService, never()).generateProductProduce(any(), anyBoolean());
        verify(productProduceService, never()).generateProductProduce(any(), anyBoolean(), any());
        verify(taskService, never()).updateProducedQuantity(anyLong(), any(), any(), any());
    }
@@ -349,11 +387,13 @@
                .thenReturn(routeProcess);
        // 调用,应该抛异常
        MesProFeedbackApproveReqVO reqVO = new MesProFeedbackApproveReqVO();
        reqVO.setId(feedback.getId());
        assertThrows(Exception.class, () ->
                feedbackService.approveFeedback(feedback.getId()));
                feedbackService.approveFeedback(reqVO));
        // 断言:不应该执行任何后续操作
        verify(productProduceService, never()).generateProductProduce(any(), anyBoolean());
        verify(productProduceService, never()).generateProductProduce(any(), anyBoolean(), any());
        verify(itemConsumeService, never()).generateItemConsume(any());
    }
@@ -380,7 +420,9 @@
                .thenReturn(routeProcess);
        // 调用
        boolean result = feedbackService.approveFeedback(feedback.getId());
        MesProFeedbackApproveReqVO reqVO = new MesProFeedbackApproveReqVO();
        reqVO.setId(feedback.getId());
        boolean result = feedbackService.approveFeedback(reqVO);
        // 断言 1:返回 true(直接完成,不走 UNCHECK)
        assertTrue(result);
@@ -391,7 +433,24 @@
        assertEquals(0, BigDecimal.ZERO.compareTo(updated.getUncheckQuantity()));
        // 断言 3:非关键工序不生成产出单
        verify(productProduceService, never()).generateProductProduce(any(), anyBoolean());
        verify(productProduceService, never()).generateProductProduce(any(), anyBoolean(), any());
    }
    /** 清除随机生成的累计数量,便于断言本次检验的回写结果 */
    private void resetFeedbackQuantities(MesProFeedbackDO feedback) {
        feedback.setQualifiedQuantity(BigDecimal.ZERO);
        feedback.setUnqualifiedQuantity(BigDecimal.ZERO);
        feedback.setLaborScrapQuantity(BigDecimal.ZERO);
        feedback.setMaterialScrapQuantity(BigDecimal.ZERO);
        feedback.setOtherScrapQuantity(BigDecimal.ZERO);
        feedback.setUncheckQuantity(BigDecimal.ZERO);
    }
    /** 末道工序返回当前报工工序,验证任务与工单的进度回写 */
    private void mockLastProcess(Long processId) {
        MesProWorkOrderProcessDO lastProcess = new MesProWorkOrderProcessDO();
        lastProcess.setProcessId(processId);
        when(workOrderProcessService.getLastWorkOrderProcessByWorkOrderId(any())).thenReturn(lastProcess);
    }
}