From cba32552d5cf1964bb022695695e09399e4bf012 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Wed, 4 Mar 2026 22:42:07 +0800 Subject: [PATCH] ✨ feat(mes): 添加 MES 编码生成策略的单元测试 --- yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/md/autocode/MesMdAutoCodeRecordMapper.java | 11 ----------- yudao-module-mes/src/test/java/cn/iocoder/yudao/module/mes/service/md/autocode/MesMdAutoCodeRecordServiceImplTest.java | 175 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ yudao-module-mes/src/test/java/cn/iocoder/yudao/module/mes/service/md/autocode/strategy/impl/MesMdAutoCodeDatePartStrategyTest.java | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ yudao-module-mes/src/test/java/cn/iocoder/yudao/module/mes/service/md/autocode/strategy/impl/MesMdAutoCodeFixedCharPartStrategyTest.java | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ yudao-module-mes/src/test/java/cn/iocoder/yudao/module/mes/service/md/autocode/strategy/impl/MesMdAutoCodeInputCharPartStrategyTest.java | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ yudao-module-mes/src/test/java/cn/iocoder/yudao/module/mes/service/md/autocode/strategy/impl/MesMdAutoCodeSerialNumberPartStrategyTest.java | 100 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ yudao-module-mes/src/test/resources/application-unit-test.yaml | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ yudao-module-mes/src/test/resources/logback.xml | 4 ++++ yudao-module-mes/src/test/resources/sql/clean.sql | 3 +++ yudao-module-mes/src/test/resources/sql/create_tables.sql | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 10 files changed, 563 insertions(+), 11 deletions(-) create mode 100644 yudao-module-mes/src/test/java/cn/iocoder/yudao/module/mes/service/md/autocode/MesMdAutoCodeRecordServiceImplTest.java create mode 100644 yudao-module-mes/src/test/java/cn/iocoder/yudao/module/mes/service/md/autocode/strategy/impl/MesMdAutoCodeDatePartStrategyTest.java create mode 100644 yudao-module-mes/src/test/java/cn/iocoder/yudao/module/mes/service/md/autocode/strategy/impl/MesMdAutoCodeFixedCharPartStrategyTest.java create mode 100644 yudao-module-mes/src/test/java/cn/iocoder/yudao/module/mes/service/md/autocode/strategy/impl/MesMdAutoCodeInputCharPartStrategyTest.java create mode 100644 yudao-module-mes/src/test/java/cn/iocoder/yudao/module/mes/service/md/autocode/strategy/impl/MesMdAutoCodeSerialNumberPartStrategyTest.java create mode 100644 yudao-module-mes/src/test/resources/application-unit-test.yaml create mode 100644 yudao-module-mes/src/test/resources/logback.xml create mode 100644 yudao-module-mes/src/test/resources/sql/clean.sql create mode 100644 yudao-module-mes/src/test/resources/sql/create_tables.sql diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/md/autocode/MesMdAutoCodeRecordMapper.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/md/autocode/MesMdAutoCodeRecordMapper.java index ed6625c..13aa301 100644 --- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/md/autocode/MesMdAutoCodeRecordMapper.java +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/md/autocode/MesMdAutoCodeRecordMapper.java @@ -1,9 +1,6 @@ package cn.iocoder.yudao.module.mes.dal.mysql.md.autocode; -import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; -import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; -import cn.iocoder.yudao.module.mes.controller.admin.md.autocode.vo.record.MesMdAutoCodeRecordPageReqVO; import cn.iocoder.yudao.module.mes.dal.dataobject.md.autocode.MesMdAutoCodeRecordDO; import org.apache.ibatis.annotations.Mapper; @@ -15,14 +12,6 @@ import org.apache.ibatis.annotations.Mapper; @Mapper public interface MesMdAutoCodeRecordMapper extends BaseMapperX { - default PageResult selectPage(MesMdAutoCodeRecordPageReqVO reqVO) { - return selectPage(reqVO, new LambdaQueryWrapperX() - .eqIfPresent(MesMdAutoCodeRecordDO::getRuleId, reqVO.getRuleId()) - .likeIfPresent(MesMdAutoCodeRecordDO::getResult, reqVO.getResult()) - .betweenIfPresent(MesMdAutoCodeRecordDO::getCreateTime, reqVO.getCreateTime()) - .orderByDesc(MesMdAutoCodeRecordDO::getId)); - } - default MesMdAutoCodeRecordDO selectByResult(String result) { return selectOne(MesMdAutoCodeRecordDO::getResult, result); } diff --git a/yudao-module-mes/src/test/java/cn/iocoder/yudao/module/mes/service/md/autocode/MesMdAutoCodeRecordServiceImplTest.java b/yudao-module-mes/src/test/java/cn/iocoder/yudao/module/mes/service/md/autocode/MesMdAutoCodeRecordServiceImplTest.java new file mode 100644 index 0000000..bf56b99 --- /dev/null +++ b/yudao-module-mes/src/test/java/cn/iocoder/yudao/module/mes/service/md/autocode/MesMdAutoCodeRecordServiceImplTest.java @@ -0,0 +1,175 @@ +package cn.iocoder.yudao.module.mes.service.md.autocode; + +import cn.hutool.core.util.ReflectUtil; +import cn.iocoder.yudao.module.mes.dal.dataobject.md.autocode.MesMdAutoCodePartDO; +import cn.iocoder.yudao.module.mes.dal.dataobject.md.autocode.MesMdAutoCodeRecordDO; +import cn.iocoder.yudao.module.mes.dal.dataobject.md.autocode.MesMdAutoCodeRuleDO; +import cn.iocoder.yudao.module.mes.dal.mysql.md.autocode.MesMdAutoCodeRecordMapper; +import cn.iocoder.yudao.module.mes.enums.md.autocode.MesMdAutoCodePartTypeEnum; +import cn.iocoder.yudao.module.mes.service.md.autocode.strategy.MesMdAutoCodeContext; +import cn.iocoder.yudao.module.mes.service.md.autocode.strategy.MesMdAutoCodePartStrategy; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.ArgumentCaptor; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +import java.util.Arrays; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.ArgumentMatchers.*; +import static org.mockito.Mockito.*; + +/** + * {@link MesMdAutoCodeRecordServiceImpl} 的单元测试 + * + * @author 芋道源码 + */ +@ExtendWith(MockitoExtension.class) +public class MesMdAutoCodeRecordServiceImplTest { + + @InjectMocks + private MesMdAutoCodeRecordServiceImpl recordService; + + @Mock + private MesMdAutoCodeRecordMapper recordMapper; + + @Mock + private MesMdAutoCodeRuleService ruleService; + @Mock + private MesMdAutoCodePartService partService; + + @Mock + private MesMdAutoCodePartStrategy fixedCharStrategy; + @Mock + private MesMdAutoCodePartStrategy serialNumberStrategy; + @Mock + private MesMdAutoCodePartStrategy inputCharStrategy; + @Mock + private MesMdAutoCodePartStrategy dateStrategy; + + @BeforeEach + public void setUp() { + // 使用反射注入 strategyList + List strategyList = Arrays.asList( + fixedCharStrategy, serialNumberStrategy, inputCharStrategy, dateStrategy + ); + when(fixedCharStrategy.getType()).thenReturn(MesMdAutoCodePartTypeEnum.FIXED_CHAR.getType()); + when(serialNumberStrategy.getType()).thenReturn(MesMdAutoCodePartTypeEnum.SERIAL_NUMBER.getType()); + when(inputCharStrategy.getType()).thenReturn(MesMdAutoCodePartTypeEnum.INPUT_CHAR.getType()); + when(dateStrategy.getType()).thenReturn(MesMdAutoCodePartTypeEnum.DATE.getType()); + ReflectUtil.setFieldValue(recordService, "strategyList", strategyList); + // 手动调用 init 方法初始化策略 map + recordService.init(); + } + + @Test + public void testGenerateAutoCode_fixedCharAndSerialNumber() { + // 准备参数 + String ruleCode = "ITEM_CODE"; + MesMdAutoCodeRuleDO rule = new MesMdAutoCodeRuleDO().setId(1L).setCode(ruleCode).setPadded(false); + MesMdAutoCodePartDO part1 = new MesMdAutoCodePartDO().setType(MesMdAutoCodePartTypeEnum.FIXED_CHAR.getType()) + .setFixCharacter("ITEM_").setLength(5).setSort(1); + MesMdAutoCodePartDO part2 = new MesMdAutoCodePartDO().setType(MesMdAutoCodePartTypeEnum.SERIAL_NUMBER.getType()) + .setSerialStartNo(1).setSerialStep(1).setLength(4).setSort(2).setCycleFlag(false); + // mock + when(ruleService.getAutoCodeRuleByCode(ruleCode)).thenReturn(rule); + when(partService.getAutoCodePartListByRuleId(1L)).thenReturn(Arrays.asList(part1, part2)); + when(fixedCharStrategy.generate(eq(part1), any(MesMdAutoCodeContext.class))).thenReturn("ITEM_"); + when(serialNumberStrategy.generate(eq(part2), any(MesMdAutoCodeContext.class))).thenAnswer(invocation -> { + MesMdAutoCodeContext context = invocation.getArgument(1); + context.setSerialNo(1); + return "0001"; + }); + when(recordMapper.selectByResult("ITEM_0001")).thenReturn(null); + + // 调用 + String result = recordService.generateAutoCode(ruleCode, null); + // 断言 + assertEquals("ITEM_0001", result); + ArgumentCaptor captor = ArgumentCaptor.forClass(MesMdAutoCodeRecordDO.class); + verify(recordMapper).insert(captor.capture()); + MesMdAutoCodeRecordDO record = captor.getValue(); + assertEquals(1L, record.getRuleId()); + assertEquals("ITEM_0001", record.getResult()); + assertEquals(1, record.getSerialNo()); + } + + @Test + public void testGenerateAutoCode_withInputChar() { + // 准备参数 + String ruleCode = "CLIENT_CODE"; + String inputChar = "A"; + MesMdAutoCodeRuleDO rule = new MesMdAutoCodeRuleDO().setId(2L).setCode(ruleCode).setPadded(false); + MesMdAutoCodePartDO part1 = new MesMdAutoCodePartDO().setType(MesMdAutoCodePartTypeEnum.INPUT_CHAR.getType()) + .setLength(1).setSort(1); + MesMdAutoCodePartDO part2 = new MesMdAutoCodePartDO().setType(MesMdAutoCodePartTypeEnum.SERIAL_NUMBER.getType()) + .setSerialStartNo(1).setSerialStep(1).setLength(4).setSort(2).setCycleFlag(false); + // mock + when(ruleService.getAutoCodeRuleByCode(ruleCode)).thenReturn(rule); + when(partService.getAutoCodePartListByRuleId(2L)).thenReturn(Arrays.asList(part1, part2)); + when(inputCharStrategy.generate(eq(part1), any(MesMdAutoCodeContext.class))).thenReturn("A"); + when(serialNumberStrategy.generate(eq(part2), any(MesMdAutoCodeContext.class))).thenReturn("0001"); + when(recordMapper.selectByResult("A0001")).thenReturn(null); + + // 调用 + String result = recordService.generateAutoCode(ruleCode, inputChar); + // 断言 + assertEquals("A0001", result); + ArgumentCaptor captor = ArgumentCaptor.forClass(MesMdAutoCodeRecordDO.class); + verify(recordMapper).insert(captor.capture()); + MesMdAutoCodeRecordDO record = captor.getValue(); + assertEquals(inputChar, record.getInputChar()); + assertEquals("A0001", record.getResult()); + } + + @Test + public void testGenerateAutoCode_withPadding() { + // 准备参数 + String ruleCode = "PADDED_CODE"; + MesMdAutoCodeRuleDO rule = new MesMdAutoCodeRuleDO().setId(3L).setCode(ruleCode) + .setPadded(true).setMaxLength(10).setPaddedChar("0").setPaddedMethod(1); + MesMdAutoCodePartDO part1 = new MesMdAutoCodePartDO().setType(MesMdAutoCodePartTypeEnum.FIXED_CHAR.getType()) + .setFixCharacter("IT").setLength(2).setSort(1); + // mock + when(ruleService.getAutoCodeRuleByCode(ruleCode)).thenReturn(rule); + when(partService.getAutoCodePartListByRuleId(3L)).thenReturn(Arrays.asList(part1)); + when(fixedCharStrategy.generate(eq(part1), any(MesMdAutoCodeContext.class))).thenReturn("IT"); + when(recordMapper.selectByResult("00000000IT")).thenReturn(null); + + // 调用 + String result = recordService.generateAutoCode(ruleCode, null); + // 断言:IT 补齐到 10 位,左补 0 + assertEquals("00000000IT", result); + verify(recordMapper).insert(any(MesMdAutoCodeRecordDO.class)); + } + + @Test + public void testGenerateAutoCode_withDatePart() { + // 准备参数 + String ruleCode = "DATE_CODE"; + MesMdAutoCodeRuleDO rule = new MesMdAutoCodeRuleDO().setId(4L).setCode(ruleCode).setPadded(false); + MesMdAutoCodePartDO part1 = new MesMdAutoCodePartDO().setType(MesMdAutoCodePartTypeEnum.DATE.getType()) + .setDateFormat("yyyyMMdd").setLength(8).setSort(1); + MesMdAutoCodePartDO part2 = new MesMdAutoCodePartDO().setType(MesMdAutoCodePartTypeEnum.SERIAL_NUMBER.getType()) + .setSerialStartNo(1).setSerialStep(1).setLength(4).setSort(2).setCycleFlag(false); + + // mock + when(ruleService.getAutoCodeRuleByCode(ruleCode)).thenReturn(rule); + when(partService.getAutoCodePartListByRuleId(4L)).thenReturn(Arrays.asList(part1, part2)); + when(dateStrategy.generate(eq(part1), any(MesMdAutoCodeContext.class))).thenReturn("20260304"); + when(serialNumberStrategy.generate(eq(part2), any(MesMdAutoCodeContext.class))).thenReturn("0001"); + when(recordMapper.selectByResult("202603040001")).thenReturn(null); + + // 调用 + String result = recordService.generateAutoCode(ruleCode, null); + // 断言:日期 8 位 + 流水号 4 位 = 12 位 + assertEquals(12, result.length()); + assertEquals("202603040001", result); + verify(recordMapper).insert(any(MesMdAutoCodeRecordDO.class)); + } + +} diff --git a/yudao-module-mes/src/test/java/cn/iocoder/yudao/module/mes/service/md/autocode/strategy/impl/MesMdAutoCodeDatePartStrategyTest.java b/yudao-module-mes/src/test/java/cn/iocoder/yudao/module/mes/service/md/autocode/strategy/impl/MesMdAutoCodeDatePartStrategyTest.java new file mode 100644 index 0000000..9ab9f1d --- /dev/null +++ b/yudao-module-mes/src/test/java/cn/iocoder/yudao/module/mes/service/md/autocode/strategy/impl/MesMdAutoCodeDatePartStrategyTest.java @@ -0,0 +1,59 @@ +package cn.iocoder.yudao.module.mes.service.md.autocode.strategy.impl; + +import cn.iocoder.yudao.module.mes.dal.dataobject.md.autocode.MesMdAutoCodePartDO; +import cn.iocoder.yudao.module.mes.service.md.autocode.strategy.MesMdAutoCodeContext; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +/** + * {@link MesMdAutoCodeDatePartStrategy} 的单元测试 + * + * @author 芋道源码 + */ +public class MesMdAutoCodeDatePartStrategyTest { + + private final MesMdAutoCodeDatePartStrategy strategy = new MesMdAutoCodeDatePartStrategy(); + + @Test + public void testGenerate_withDefaultFormat() { + // 准备参数 + MesMdAutoCodePartDO part = new MesMdAutoCodePartDO().setDateFormat(null); + MesMdAutoCodeContext context = new MesMdAutoCodeContext(); + + // 调用 + String result = strategy.generate(part, context); + + // 断言:默认格式为 yyyyMMdd,长度为 8 + assertEquals(8, result.length()); + assertTrue(result.matches("\\d{8}")); + } + + @Test + public void testGenerate_withCustomFormat() { + // 准备参数 + MesMdAutoCodePartDO part = new MesMdAutoCodePartDO().setDateFormat("yyyyMM"); + MesMdAutoCodeContext context = new MesMdAutoCodeContext(); + + // 调用 + String result = strategy.generate(part, context); + // 断言:格式为 yyyyMM,长度为 6 + assertEquals(6, result.length()); + assertTrue(result.matches("\\d{6}")); + } + + @Test + public void testGenerate_withTimeFormat() { + // 准备参数 + MesMdAutoCodePartDO part = new MesMdAutoCodePartDO().setDateFormat("HHmmss"); + MesMdAutoCodeContext context = new MesMdAutoCodeContext(); + + // 调用 + String result = strategy.generate(part, context); + // 断言:格式为 HHmmss,长度为 6 + assertEquals(6, result.length()); + assertTrue(result.matches("\\d{6}")); + } + +} diff --git a/yudao-module-mes/src/test/java/cn/iocoder/yudao/module/mes/service/md/autocode/strategy/impl/MesMdAutoCodeFixedCharPartStrategyTest.java b/yudao-module-mes/src/test/java/cn/iocoder/yudao/module/mes/service/md/autocode/strategy/impl/MesMdAutoCodeFixedCharPartStrategyTest.java new file mode 100644 index 0000000..8662146 --- /dev/null +++ b/yudao-module-mes/src/test/java/cn/iocoder/yudao/module/mes/service/md/autocode/strategy/impl/MesMdAutoCodeFixedCharPartStrategyTest.java @@ -0,0 +1,54 @@ +package cn.iocoder.yudao.module.mes.service.md.autocode.strategy.impl; + +import cn.iocoder.yudao.module.mes.dal.dataobject.md.autocode.MesMdAutoCodePartDO; +import cn.iocoder.yudao.module.mes.service.md.autocode.strategy.MesMdAutoCodeContext; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +/** + * {@link MesMdAutoCodeFixedCharPartStrategy} 的单元测试 + * + * @author 芋道源码 + */ +public class MesMdAutoCodeFixedCharPartStrategyTest { + + private final MesMdAutoCodeFixedCharPartStrategy strategy = new MesMdAutoCodeFixedCharPartStrategy(); + + @Test + public void testGenerate_withFixedChar() { + // 准备参数 + MesMdAutoCodePartDO part = new MesMdAutoCodePartDO().setFixCharacter("ITEM_"); + MesMdAutoCodeContext context = new MesMdAutoCodeContext(); + + // 调用 + String result = strategy.generate(part, context); + // 断言 + assertEquals("ITEM_", result); + } + + @Test + public void testGenerate_withEmptyFixedChar() { + // 准备参数 + MesMdAutoCodePartDO part = new MesMdAutoCodePartDO().setFixCharacter(""); + MesMdAutoCodeContext context = new MesMdAutoCodeContext(); + + // 调用 + String result = strategy.generate(part, context); + // 断言 + assertEquals("", result); + } + + @Test + public void testGenerate_withNullFixedChar() { + // 准备参数 + MesMdAutoCodePartDO part = new MesMdAutoCodePartDO().setFixCharacter(null); + MesMdAutoCodeContext context = new MesMdAutoCodeContext(); + + // 调用 + String result = strategy.generate(part, context); + // 断言 + assertEquals("", result); + } + +} diff --git a/yudao-module-mes/src/test/java/cn/iocoder/yudao/module/mes/service/md/autocode/strategy/impl/MesMdAutoCodeInputCharPartStrategyTest.java b/yudao-module-mes/src/test/java/cn/iocoder/yudao/module/mes/service/md/autocode/strategy/impl/MesMdAutoCodeInputCharPartStrategyTest.java new file mode 100644 index 0000000..a517381 --- /dev/null +++ b/yudao-module-mes/src/test/java/cn/iocoder/yudao/module/mes/service/md/autocode/strategy/impl/MesMdAutoCodeInputCharPartStrategyTest.java @@ -0,0 +1,54 @@ +package cn.iocoder.yudao.module.mes.service.md.autocode.strategy.impl; + +import cn.iocoder.yudao.module.mes.dal.dataobject.md.autocode.MesMdAutoCodePartDO; +import cn.iocoder.yudao.module.mes.service.md.autocode.strategy.MesMdAutoCodeContext; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +/** + * {@link MesMdAutoCodeInputCharPartStrategy} 的单元测试 + * + * @author 芋道源码 + */ +public class MesMdAutoCodeInputCharPartStrategyTest { + + private final MesMdAutoCodeInputCharPartStrategy strategy = new MesMdAutoCodeInputCharPartStrategy(); + + @Test + public void testGenerate_withInputChar() { + // 准备参数 + MesMdAutoCodePartDO part = new MesMdAutoCodePartDO(); + MesMdAutoCodeContext context = new MesMdAutoCodeContext().setInputChar("ABC"); + + // 调用 + String result = strategy.generate(part, context); + // 断言 + assertEquals("ABC", result); + } + + @Test + public void testGenerate_withEmptyInputChar() { + // 准备参数 + MesMdAutoCodePartDO part = new MesMdAutoCodePartDO(); + MesMdAutoCodeContext context = new MesMdAutoCodeContext().setInputChar(""); + + // 调用 + String result = strategy.generate(part, context); + // 断言 + assertEquals("", result); + } + + @Test + public void testGenerate_withNullInputChar() { + // 准备参数 + MesMdAutoCodePartDO part = new MesMdAutoCodePartDO(); + MesMdAutoCodeContext context = new MesMdAutoCodeContext().setInputChar(null); + + // 调用 + String result = strategy.generate(part, context); + // 断言 + assertEquals("", result); + } + +} diff --git a/yudao-module-mes/src/test/java/cn/iocoder/yudao/module/mes/service/md/autocode/strategy/impl/MesMdAutoCodeSerialNumberPartStrategyTest.java b/yudao-module-mes/src/test/java/cn/iocoder/yudao/module/mes/service/md/autocode/strategy/impl/MesMdAutoCodeSerialNumberPartStrategyTest.java new file mode 100644 index 0000000..f1e63a0 --- /dev/null +++ b/yudao-module-mes/src/test/java/cn/iocoder/yudao/module/mes/service/md/autocode/strategy/impl/MesMdAutoCodeSerialNumberPartStrategyTest.java @@ -0,0 +1,100 @@ +package cn.iocoder.yudao.module.mes.service.md.autocode.strategy.impl; + +import cn.iocoder.yudao.framework.test.core.ut.BaseRedisUnitTest; +import cn.iocoder.yudao.module.mes.dal.dataobject.md.autocode.MesMdAutoCodePartDO; +import cn.iocoder.yudao.module.mes.dal.dataobject.md.autocode.MesMdAutoCodeRuleDO; +import cn.iocoder.yudao.module.mes.dal.redis.md.autocode.MesMdAutoCodeRedisDAO; +import cn.iocoder.yudao.module.mes.enums.md.autocode.MesMdAutoCodeCycleMethodEnum; +import cn.iocoder.yudao.module.mes.service.md.autocode.strategy.MesMdAutoCodeContext; +import jakarta.annotation.Resource; +import org.junit.jupiter.api.Test; +import org.springframework.context.annotation.Import; + +import static org.junit.jupiter.api.Assertions.*; + +/** + * {@link MesMdAutoCodeSerialNumberPartStrategy} 的单元测试 + * + * @author 芋道源码 + */ +@Import({MesMdAutoCodeSerialNumberPartStrategy.class, MesMdAutoCodeRedisDAO.class}) +public class MesMdAutoCodeSerialNumberPartStrategyTest extends BaseRedisUnitTest { + + @Resource + private MesMdAutoCodeSerialNumberPartStrategy strategy; + + @Test + public void testGenerate_noCycle() { + // 准备参数 + MesMdAutoCodePartDO part = new MesMdAutoCodePartDO().setLength(4).setSerialStartNo(1).setSerialStep(1).setCycleFlag(false); + MesMdAutoCodeRuleDO rule = new MesMdAutoCodeRuleDO().setId(1L); + MesMdAutoCodeContext context = new MesMdAutoCodeContext().setRule(rule); + + // 调用 + String result = strategy.generate(part, context); + // 断言 + assertEquals("0001", result); + assertEquals(1, context.getSerialNo()); + } + + @Test + public void testGenerate_withCycleByDay() { + // 准备参数 + MesMdAutoCodePartDO part = new MesMdAutoCodePartDO().setLength(4).setSerialStartNo(1).setSerialStep(1) + .setCycleFlag(true).setCycleMethod(MesMdAutoCodeCycleMethodEnum.DAY.getMethod()); + MesMdAutoCodeRuleDO rule = new MesMdAutoCodeRuleDO().setId(2L); + MesMdAutoCodeContext context = new MesMdAutoCodeContext().setRule(rule); + + // 调用 + String result = strategy.generate(part, context); + // 断言 + assertEquals("0001", result); + assertEquals(1, context.getSerialNo()); + } + + @Test + public void testGenerate_withCycleByInputChar() { + // 准备参数 + MesMdAutoCodePartDO part = new MesMdAutoCodePartDO().setLength(4).setSerialStartNo(1).setSerialStep(1) + .setCycleFlag(true).setCycleMethod(MesMdAutoCodeCycleMethodEnum.INPUT_CHAR.getMethod()); + MesMdAutoCodeRuleDO rule = new MesMdAutoCodeRuleDO().setId(3L); + MesMdAutoCodeContext context = new MesMdAutoCodeContext().setRule(rule).setInputChar("A"); + + // 调用 + String result = strategy.generate(part, context); + // 断言 + assertEquals("0001", result); + assertEquals(1, context.getSerialNo()); + } + + @Test + public void testGenerate_withStep() { + // 准备参数 + MesMdAutoCodePartDO part = new MesMdAutoCodePartDO().setLength(4).setSerialStartNo(1).setSerialStep(5).setCycleFlag(false); + MesMdAutoCodeRuleDO rule = new MesMdAutoCodeRuleDO().setId(4L); + MesMdAutoCodeContext context = new MesMdAutoCodeContext().setRule(rule); + + // 调用 + String result = strategy.generate(part, context); + // 断言 + assertEquals("0005", result); + assertEquals(5, context.getSerialNo()); + } + + @Test + public void testGenerate_multipleCallsIncrement() { + // 准备参数 + MesMdAutoCodePartDO part = new MesMdAutoCodePartDO().setLength(4).setSerialStartNo(1).setSerialStep(1).setCycleFlag(false); + MesMdAutoCodeRuleDO rule = new MesMdAutoCodeRuleDO().setId(5L); + MesMdAutoCodeContext context1 = new MesMdAutoCodeContext().setRule(rule); + MesMdAutoCodeContext context2 = new MesMdAutoCodeContext().setRule(rule); + + // 调用 + String result1 = strategy.generate(part, context1); + String result2 = strategy.generate(part, context2); + // 断言 + assertEquals("0001", result1); + assertEquals("0002", result2); + } + +} diff --git a/yudao-module-mes/src/test/resources/application-unit-test.yaml b/yudao-module-mes/src/test/resources/application-unit-test.yaml new file mode 100644 index 0000000..6e02b80 --- /dev/null +++ b/yudao-module-mes/src/test/resources/application-unit-test.yaml @@ -0,0 +1,49 @@ +spring: + main: + lazy-initialization: true # 开启懒加载,加快速度 + banner-mode: off # 单元测试,禁用 Banner + allow-bean-definition-overriding: true # 允许 Bean 覆盖,解决 Redis 配置冲突 + +--- #################### 数据库相关配置 #################### + +spring: + # 数据源配置项 + datasource: + name: ruoyi-vue-pro + url: jdbc:h2:mem:testdb;MODE=MYSQL;DATABASE_TO_UPPER=false;NON_KEYWORDS=value; # MODE 使用 MySQL 模式;DATABASE_TO_UPPER 配置表和字段使用小写 + driver-class-name: org.h2.Driver + username: sa + password: + druid: + async-init: true # 单元测试,异步初始化 Druid 连接池,提升启动速度 + initial-size: 1 # 单元测试,配置为 1,提升启动速度 + sql: + init: + schema-locations: classpath:/sql/create_tables.sql + + # Redis 配置。Redisson 默认的配置足够使用,一般不需要进行调优 + data: + redis: + host: 127.0.0.1 # 地址 + port: 16379 # 端口(单元测试,使用 16379 端口) + database: 0 # 数据库索引 + +mybatis: + lazy-initialization: true # 单元测试,设置 MyBatis Mapper 延迟加载,加速每个单元测试 + +--- #################### 定时任务相关配置 #################### + +--- #################### 配置中心相关配置 #################### + +--- #################### 服务保障相关配置 #################### + +# Lock4j 配置项(单元测试,禁用 Lock4j) + +--- #################### 监控相关配置 #################### + +--- #################### 芋道相关配置 #################### + +# 芋道配置项,设置当前项目所有自定义的配置 +yudao: + info: + base-package: cn.iocoder.yudao.module diff --git a/yudao-module-mes/src/test/resources/logback.xml b/yudao-module-mes/src/test/resources/logback.xml new file mode 100644 index 0000000..daf756b --- /dev/null +++ b/yudao-module-mes/src/test/resources/logback.xml @@ -0,0 +1,4 @@ + + + + diff --git a/yudao-module-mes/src/test/resources/sql/clean.sql b/yudao-module-mes/src/test/resources/sql/clean.sql new file mode 100644 index 0000000..175f73c --- /dev/null +++ b/yudao-module-mes/src/test/resources/sql/clean.sql @@ -0,0 +1,3 @@ +DELETE FROM "mes_md_auto_code_rule"; +DELETE FROM "mes_md_auto_code_part"; +DELETE FROM "mes_md_auto_code_record"; diff --git a/yudao-module-mes/src/test/resources/sql/create_tables.sql b/yudao-module-mes/src/test/resources/sql/create_tables.sql new file mode 100644 index 0000000..ea7d525 --- /dev/null +++ b/yudao-module-mes/src/test/resources/sql/create_tables.sql @@ -0,0 +1,65 @@ +-- ---------------------------- +-- MES 编码规则表 +-- ---------------------------- +CREATE TABLE IF NOT EXISTS "mes_md_auto_code_rule" ( + "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY, + "code" varchar(64) NOT NULL, + "name" varchar(64) NOT NULL, + "description" varchar(255) DEFAULT NULL, + "max_length" int DEFAULT NULL, + "padded" bit NOT NULL DEFAULT FALSE, + "padded_char" varchar(1) DEFAULT NULL, + "padded_method" tinyint DEFAULT NULL, + "status" tinyint NOT NULL, + "remark" varchar(500) DEFAULT NULL, + "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") +); + +-- ---------------------------- +-- MES 编码规则组成表 +-- ---------------------------- +CREATE TABLE IF NOT EXISTS "mes_md_auto_code_part" ( + "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY, + "rule_id" bigint NOT NULL, + "sort" int NOT NULL, + "type" tinyint NOT NULL, + "length" int NOT NULL, + "date_format" varchar(20) DEFAULT NULL, + "fix_character" varchar(64) DEFAULT NULL, + "serial_start_no" int DEFAULT NULL, + "serial_step" int DEFAULT NULL, + "cycle_flag" bit DEFAULT FALSE, + "cycle_method" tinyint DEFAULT NULL, + "remark" varchar(500) DEFAULT NULL, + "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") +); + +-- ---------------------------- +-- MES 编码生成记录表 +-- ---------------------------- +CREATE TABLE IF NOT EXISTS "mes_md_auto_code_record" ( + "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY, + "rule_id" bigint NOT NULL, + "result" varchar(64) DEFAULT NULL, + "serial_no" int DEFAULT NULL, + "input_char" varchar(64) DEFAULT NULL, + "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") +); -- libgit2 0.21.4