package cn.iocoder.yudao.module.mes.service.pro.bagcode; import cn.iocoder.yudao.framework.common.exception.ServiceException; import cn.iocoder.yudao.module.mes.controller.admin.pro.pallet.vo.MesProPalletBindBatchReqVO; import cn.iocoder.yudao.module.mes.dal.dataobject.pro.pallet.MesProPalletDO; import cn.iocoder.yudao.module.mes.dal.dataobject.pro.batch.MesProBatchDO; import cn.iocoder.yudao.module.mes.dal.dataobject.pro.bagcode.MesProBagCodeDO; import cn.iocoder.yudao.module.mes.dal.mysql.pro.pallet.MesProPalletMapper; import cn.iocoder.yudao.module.mes.dal.mysql.pro.batch.MesProBatchMapper; import cn.iocoder.yudao.module.mes.dal.mysql.pro.bagcode.MesProBagCodeMapper; import cn.iocoder.yudao.module.mes.dal.redis.MesCodeRedisDAO; import cn.iocoder.yudao.module.mes.service.pro.pallet.MesProPalletServiceImpl; import org.junit.jupiter.api.*; import org.mockito.ArgumentCaptor; import org.springframework.test.util.ReflectionTestUtils; import java.util.List; import static org.junit.jupiter.api.Assertions.*; import static org.mockito.Mockito.*; class PalletItemBindingTest { final MesProPalletServiceImpl service=new MesProPalletServiceImpl(); final MesProPalletMapper pallets=mock(MesProPalletMapper.class); final MesProBatchMapper batches=mock(MesProBatchMapper.class); final MesProBagCodeMapper bags=mock(MesProBagCodeMapper.class); final MesCodeRedisDAO codes=mock(MesCodeRedisDAO.class); MesProBatchDO batch; MesProPalletBindBatchReqVO req; @BeforeEach void setup(){ ReflectionTestUtils.setField(service,"palletMapper",pallets);ReflectionTestUtils.setField(service,"batchMapper",batches); ReflectionTestUtils.setField(service,"bagCodeMapper",bags);ReflectionTestUtils.setField(service,"codeRedisDao",codes); ReflectionTestUtils.setField(service,"integrityService",mock(cn.iocoder.yudao.module.mes.service.trace.integrity.MesTraceIntegrityService.class)); batch=new MesProBatchDO().setId(8L).setCode("BATCH").setStatus(20); when(batches.selectByIdForUpdate(8L)).thenReturn(batch);when(codes.generate()).thenReturn("1234567890123456"); req=new MesProPalletBindBatchReqVO();req.setBatchId(8L);req.setIds(List.of(1L,2L)); when(pallets.selectByIdForUpdate(1L)).thenReturn(new MesProPalletDO().setId(1L).setItemId(5L).setStatus(10)); when(pallets.selectByIdForUpdate(2L)).thenReturn(new MesProPalletDO().setId(2L).setItemId(5L).setStatus(10)); } @Test void sameVarietyFillsBatchAndPallets(){ assertEquals(2,service.bindBatch(req)); var saved=ArgumentCaptor.forClass(MesProBatchDO.class);verify(batches).updateById(saved.capture());assertEquals(5L,saved.getValue().getItemId()); var savedPallet=ArgumentCaptor.forClass(MesProPalletDO.class);verify(pallets,times(2)).updateById(savedPallet.capture()); assertTrue(savedPallet.getAllValues().stream().allMatch(p->Long.valueOf(5).equals(p.getItemId()))); } @Test void mixedPalletVarietiesRejectBeforeAnyWrite(){ when(pallets.selectByIdForUpdate(2L)).thenReturn(new MesProPalletDO().setId(2L).setItemId(6L));assertRejected(); } @Test void existingBatchVarietyCannotBeOverwritten(){batch.setItemId(6L);assertRejected();} @Test void existingBatchBagsAlsoConstrainVariety(){when(bags.selectDistinctItemIdsByBatchId(8L)).thenReturn(List.of(6L));assertRejected();} @Test void palletMetadataCannotHideMixedBagVarieties(){ when(bags.selectListByPalletId(1L)).thenReturn(List.of(new MesProBagCodeDO().setItemId(6L).setStatus(10)));assertRejected(); } @Test void missingVarietyCannotBeBound(){when(pallets.selectByIdForUpdate(2L)).thenReturn(new MesProPalletDO().setId(2L));assertRejected();} @Test void historicalPalletInfersVarietyFromBags(){ when(pallets.selectByIdForUpdate(1L)).thenReturn(new MesProPalletDO().setId(1L)); when(bags.selectListByPalletId(1L)).thenReturn(List.of(new MesProBagCodeDO().setItemId(5L).setStatus(10),new MesProBagCodeDO().setItemId(6L).setStatus(30))); assertEquals(2,service.bindBatch(req)); } @Test void batchCreateCannotForgeVarietyDifferentFromSelectedPallet(){ var batchService=new cn.iocoder.yudao.module.mes.service.pro.batch.MesProBatchServiceImpl(); ReflectionTestUtils.setField(batchService,"palletMapper",pallets);ReflectionTestUtils.setField(batchService,"bagCodeMapper",bags); ReflectionTestUtils.setField(batchService,"adminUserApi",mock(cn.iocoder.yudao.module.system.api.user.AdminUserApi.class)); var lines=mock(cn.iocoder.yudao.module.mes.service.pro.line.MesProLineService.class); ReflectionTestUtils.setField(batchService,"lineService",lines); when(lines.validateLineExistsAndEnable(1L)).thenReturn(new cn.iocoder.yudao.module.mes.dal.dataobject.pro.line.MesProLineDO().setId(1L)); var request=new cn.iocoder.yudao.module.mes.controller.admin.pro.batch.vo.MesProBatchSaveReqVO(); request.setLineId(1L);request.setItemId(99L);request.setPalletIds(List.of(1L));request.setWorkers(List.of()); assertThrows(ServiceException.class,()->batchService.createBatch(request)); } @Test void editingBatchCannotChangeItsExistingVariety(){ var batchService=new cn.iocoder.yudao.module.mes.service.pro.batch.MesProBatchServiceImpl(); ReflectionTestUtils.setField(batchService,"batchMapper",batches);ReflectionTestUtils.setField(batchService,"palletMapper",pallets); ReflectionTestUtils.setField(batchService,"bagCodeMapper",bags); ReflectionTestUtils.setField(batchService,"adminUserApi",mock(cn.iocoder.yudao.module.system.api.user.AdminUserApi.class)); batch.setItemId(5L); var request=new cn.iocoder.yudao.module.mes.controller.admin.pro.batch.vo.MesProBatchSaveReqVO(); request.setId(8L);request.setItemId(99L);request.setWorkers(List.of()); assertThrows(ServiceException.class,()->batchService.updateBatch(request));verify(batches,never()).updateById(any(MesProBatchDO.class)); } void assertRejected(){assertThrows(ServiceException.class,()->service.bindBatch(req));verify(pallets,never()).updateById(any(MesProPalletDO.class));verify(batches,never()).updateById(any(MesProBatchDO.class));verifyNoInteractions(codes);} }