From 2e87bf70aafd5e2a1a1192ee7918f8dfb2168dfb Mon Sep 17 00:00:00 2001 From: zhouz <> Date: Wed, 22 Jul 2026 14:42:58 +0800 Subject: [PATCH] =?UTF-8?q?test:=20=E4=BD=BF=E7=94=A8=20H2=20=E9=AA=8C?= =?UTF-8?q?=E8=AF=81=E5=8F=AF=E7=94=A8=E5=BA=93=E5=AD=98=E6=9F=A5=E8=AF=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- nl-module-wms/nl-module-wms-server/pom.xml | 12 ++ .../iostorinvdtl/IostorinvDtlMapperTest.java | 111 ++++++++++++++++++ .../iostorinv/IostorInvServiceImplTest.java | 78 ------------ .../sql/iostorinv/available-inventory.sql | 56 +++++++++ 4 files changed, 179 insertions(+), 78 deletions(-) create mode 100644 nl-module-wms/nl-module-wms-server/src/test/java/cn/code/nl/module/wms/dal/mysql/iostorinvdtl/IostorinvDtlMapperTest.java delete mode 100644 nl-module-wms/nl-module-wms-server/src/test/java/cn/code/nl/module/wms/service/iostorinv/IostorInvServiceImplTest.java create mode 100644 nl-module-wms/nl-module-wms-server/src/test/resources/sql/iostorinv/available-inventory.sql diff --git a/nl-module-wms/nl-module-wms-server/pom.xml b/nl-module-wms/nl-module-wms-server/pom.xml index 4142363f..26dc0cdf 100644 --- a/nl-module-wms/nl-module-wms-server/pom.xml +++ b/nl-module-wms/nl-module-wms-server/pom.xml @@ -129,6 +129,18 @@ cn.nl.cloud nl-spring-boot-starter-monitor + + + + org.springframework.boot + spring-boot-starter-test + test + + + com.h2database + h2 + test + diff --git a/nl-module-wms/nl-module-wms-server/src/test/java/cn/code/nl/module/wms/dal/mysql/iostorinvdtl/IostorinvDtlMapperTest.java b/nl-module-wms/nl-module-wms-server/src/test/java/cn/code/nl/module/wms/dal/mysql/iostorinvdtl/IostorinvDtlMapperTest.java new file mode 100644 index 00000000..8b673002 --- /dev/null +++ b/nl-module-wms/nl-module-wms-server/src/test/java/cn/code/nl/module/wms/dal/mysql/iostorinvdtl/IostorinvDtlMapperTest.java @@ -0,0 +1,111 @@ +package cn.code.nl.module.wms.dal.mysql.iostorinvdtl; + +import cn.code.nl.framework.common.pojo.PageResult; +import cn.code.nl.module.wms.controller.admin.iostorinv.vo.AvailableInventoryPageReqVO; +import cn.code.nl.module.wms.controller.admin.iostorinv.vo.AvailableInventoryRespVO; +import cn.code.nl.module.wms.controller.admin.iostorinv.vo.ExpandAvailableInventoryReqVO; +import cn.code.nl.module.wms.service.iostorinv.IostorInvServiceImpl; +import com.baomidou.mybatisplus.annotation.DbType; +import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor; +import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor; +import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean; +import org.apache.ibatis.session.SqlSessionFactory; +import org.junit.jupiter.api.Test; +import org.mybatis.spring.annotation.MapperScan; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.jdbc.datasource.DataSourceTransactionManager; +import org.springframework.jdbc.datasource.DriverManagerDataSource; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.jdbc.Sql; +import org.springframework.test.context.junit.jupiter.SpringJUnitConfig; +import org.springframework.transaction.PlatformTransactionManager; +import org.springframework.transaction.annotation.Transactional; + +import javax.sql.DataSource; +import jakarta.annotation.Resource; +import java.lang.reflect.Field; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +@SpringJUnitConfig +@ContextConfiguration(classes = IostorinvDtlMapperTest.TestConfiguration.class) +@Sql("/sql/iostorinv/available-inventory.sql") +@Transactional +class IostorinvDtlMapperTest { + + @Resource + private IostorinvDtlMapper mapper; + + @Test + void shouldExpandAvailableChildrenAndExecutePageFilters() throws Exception { + IostorInvServiceImpl service = new IostorInvServiceImpl(); + Field mapperField = IostorInvServiceImpl.class.getDeclaredField("iostorinvDtlMapper"); + mapperField.setAccessible(true); + mapperField.set(service, mapper); + + ExpandAvailableInventoryReqVO expandReqVO = new ExpandAvailableInventoryReqVO(); + expandReqVO.setStorId("STOR-001"); + expandReqVO.setVehicleCodes(List.of("BOX-001", "BOX-001")); + List expanded = service.expandAvailableInventory(expandReqVO); + + assertEquals(2, expanded.size()); + assertTrue(expanded.stream().allMatch(item -> "BOX-001".equals(item.getVehicleCode()))); + assertTrue(expanded.stream().allMatch(item -> "STOR-001".equals(item.getStorId()))); + assertEquals(2, expanded.stream().map(AvailableInventoryRespVO::getPcsn).distinct().count()); + assertTrue(expanded.stream().allMatch(item -> item.getAvailableQty().signum() > 0)); + + AvailableInventoryPageReqVO warehousePageReqVO = new AvailableInventoryPageReqVO(); + warehousePageReqVO.setStorId("STOR-001"); + warehousePageReqVO.setPageNo(1); + warehousePageReqVO.setPageSize(10); + PageResult warehousePage = mapper.selectAvailableInventoryPage(warehousePageReqVO); + assertEquals(2L, warehousePage.getTotal()); + + AvailableInventoryPageReqVO pageReqVO = new AvailableInventoryPageReqVO(); + pageReqVO.setStorId("STOR-001"); + pageReqVO.setMaterialCode("MAT-001"); + pageReqVO.setVehicleCode("BOX-001"); + pageReqVO.setPcsn("PCSN-002"); + pageReqVO.setPageNo(1); + pageReqVO.setPageSize(10); + PageResult page = mapper.selectAvailableInventoryPage(pageReqVO); + + assertEquals(1L, page.getTotal()); + assertEquals("PCSN-002", page.getList().get(0).getPcsn()); + assertEquals("材料一", page.getList().get(0).getMaterialName()); + } + + @Configuration(proxyBeanMethods = false) + @MapperScan(basePackageClasses = IostorinvDtlMapper.class) + static class TestConfiguration { + + @Bean + DataSource dataSource() { + return new DriverManagerDataSource("jdbc:h2:mem:available_inventory;MODE=MySQL;DB_CLOSE_DELAY=-1", "sa", ""); + } + + @Bean + SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception { + MybatisSqlSessionFactoryBean factory = new MybatisSqlSessionFactoryBean(); + factory.setDataSource(dataSource); + factory.setMapperLocations(new org.springframework.core.io.ClassPathResource( + "mapper/iostorinvdtl/IostorinvDtlMapper.xml")); + org.apache.ibatis.session.Configuration configuration = new org.apache.ibatis.session.Configuration(); + configuration.setMapUnderscoreToCamelCase(true); + factory.setConfiguration(configuration); + MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); + interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.H2)); + factory.setPlugins(interceptor); + return factory.getObject(); + } + + @Bean + PlatformTransactionManager transactionManager(DataSource dataSource) { + return new DataSourceTransactionManager(dataSource); + } + } + +} diff --git a/nl-module-wms/nl-module-wms-server/src/test/java/cn/code/nl/module/wms/service/iostorinv/IostorInvServiceImplTest.java b/nl-module-wms/nl-module-wms-server/src/test/java/cn/code/nl/module/wms/service/iostorinv/IostorInvServiceImplTest.java deleted file mode 100644 index c2c9c1f6..00000000 --- a/nl-module-wms/nl-module-wms-server/src/test/java/cn/code/nl/module/wms/service/iostorinv/IostorInvServiceImplTest.java +++ /dev/null @@ -1,78 +0,0 @@ -package cn.code.nl.module.wms.service.iostorinv; - -import cn.code.nl.module.wms.controller.admin.iostorinv.vo.AvailableInventoryRespVO; -import cn.code.nl.module.wms.controller.admin.iostorinv.vo.ExpandAvailableInventoryReqVO; -import cn.code.nl.module.wms.dal.mysql.iostorinvdtl.IostorinvDtlMapper; -import org.junit.jupiter.api.Test; - -import java.io.InputStream; -import java.lang.reflect.Field; -import java.lang.reflect.Proxy; -import java.nio.charset.StandardCharsets; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertTrue; - -class IostorInvServiceImplTest { - - @Test - @SuppressWarnings("unchecked") - void expandAvailableInventoryShouldDeduplicateBoxesAndKeepWarehouseIsolation() throws Exception { - List queriedVehicleCodes = new ArrayList<>(); - IostorinvDtlMapper mapper = (IostorinvDtlMapper) Proxy.newProxyInstance( - IostorinvDtlMapper.class.getClassLoader(), new Class[]{IostorinvDtlMapper.class}, - (proxy, method, args) -> { - if (!"selectAvailableInventoryByVehicleCodes".equals(method.getName())) { - throw new UnsupportedOperationException(method.getName()); - } - assertEquals("STOR-001", args[0]); - queriedVehicleCodes.addAll((Collection) args[1]); - return List.of(inventory("BOX-001", "PCSN-001", "STOR-001"), - inventory("BOX-001", "PCSN-002", "STOR-001")); - }); - IostorInvServiceImpl service = new IostorInvServiceImpl(); - Field mapperField = IostorInvServiceImpl.class.getDeclaredField("iostorinvDtlMapper"); - mapperField.setAccessible(true); - mapperField.set(service, mapper); - - ExpandAvailableInventoryReqVO reqVO = new ExpandAvailableInventoryReqVO(); - reqVO.setStorId("STOR-001"); - reqVO.setVehicleCodes(List.of("BOX-001", "BOX-001")); - - List result = service.expandAvailableInventory(reqVO); - - assertEquals(List.of("BOX-001"), queriedVehicleCodes); - assertEquals(2, result.size()); - assertTrue(result.stream().allMatch(item -> "BOX-001".equals(item.getVehicleCode()))); - assertTrue(result.stream().allMatch(item -> "STOR-001".equals(item.getStorId()))); - assertEquals(2, result.stream().map(AvailableInventoryRespVO::getPcsn).distinct().count()); - } - - @Test - void availableInventorySqlShouldFilterWarehouseStatusDeletedAndAvailableQuantity() throws Exception { - String mapperResource = "mapper/iostorinvdtl/IostorinvDtlMapper.xml"; - try (InputStream input = Thread.currentThread().getContextClassLoader().getResourceAsStream(mapperResource)) { - assertNotNull(input, "Mapper XML 应存在于测试类路径"); - String sql = new String(input.readAllBytes(), StandardCharsets.UTF_8); - assertTrue(sql.contains("sa.stor_id = #{storId}")); - assertTrue(sql.contains("gp.status = '可用'")); - assertTrue(sql.contains("gp.qty - gp.frozen_qty > 0")); - assertTrue(sql.contains("gp.deleted = 0")); - assertTrue(sql.contains("sa.deleted = 0")); - assertTrue(sql.contains("mb.deleted = 0")); - } - } - - private static AvailableInventoryRespVO inventory(String vehicleCode, String pcsn, String storId) { - AvailableInventoryRespVO inventory = new AvailableInventoryRespVO(); - inventory.setVehicleCode(vehicleCode); - inventory.setPcsn(pcsn); - inventory.setStorId(storId); - return inventory; - } - -} diff --git a/nl-module-wms/nl-module-wms-server/src/test/resources/sql/iostorinv/available-inventory.sql b/nl-module-wms/nl-module-wms-server/src/test/resources/sql/iostorinv/available-inventory.sql new file mode 100644 index 00000000..8d08b35b --- /dev/null +++ b/nl-module-wms/nl-module-wms-server/src/test/resources/sql/iostorinv/available-inventory.sql @@ -0,0 +1,56 @@ +DROP TABLE IF EXISTS wms_group_plate; +DROP TABLE IF EXISTS wms_structattr; +DROP TABLE IF EXISTS base_materialbase; + +CREATE TABLE base_materialbase ( + material_id BIGINT PRIMARY KEY, + material_name VARCHAR(64), + deleted BOOLEAN NOT NULL +); + +CREATE TABLE wms_structattr ( + struct_id VARCHAR(64) PRIMARY KEY, + storagevehicle_code VARCHAR(64), + stor_id VARCHAR(64), + stor_code VARCHAR(64), + stor_name VARCHAR(64), + deleted BOOLEAN NOT NULL +); + +CREATE TABLE wms_group_plate ( + group_id BIGINT PRIMARY KEY, + vehicle_code VARCHAR(64), + status VARCHAR(16), + material_id VARCHAR(64), + material_code VARCHAR(64), + pcsn VARCHAR(64), + qty DECIMAL(18, 6), + frozen_qty DECIMAL(18, 6), + qty_unit_id VARCHAR(64), + qty_unit_name VARCHAR(64), + ext_code VARCHAR(64), + ext_type VARCHAR(64), + ext_dtl_code VARCHAR(64), + deleted BOOLEAN NOT NULL +); + +INSERT INTO base_materialbase(material_id, material_name, deleted) +VALUES (1001, '材料一', FALSE), (1002, '已删除材料', TRUE); + +INSERT INTO wms_structattr(struct_id, storagevehicle_code, stor_id, stor_code, stor_name, deleted) +VALUES ('S-001', 'BOX-001', 'STOR-001', 'STOR-CODE-001', '一号仓', FALSE), + ('S-002', 'BOX-001', 'STOR-002', 'STOR-CODE-002', '二号仓', FALSE), + ('S-003', 'BOX-002', 'STOR-001', 'STOR-CODE-001', '一号仓', FALSE), + ('S-004', 'BOX-003', 'STOR-001', 'STOR-CODE-001', '一号仓', FALSE), + ('S-005', 'BOX-004', 'STOR-001', 'STOR-CODE-001', '一号仓', FALSE), + ('S-006', 'BOX-005', 'STOR-001', 'STOR-CODE-001', '一号仓', TRUE); + +INSERT INTO wms_group_plate(group_id, vehicle_code, status, material_id, material_code, pcsn, + qty, frozen_qty, qty_unit_id, qty_unit_name, ext_code, ext_type, + ext_dtl_code, deleted) +VALUES (1, 'BOX-001', '可用', '1001', 'MAT-001', 'PCSN-001', 10, 2, 'UNIT-1', '卷', 'EXT-1', 'TYPE-1', 'DTL-1', FALSE), + (2, 'BOX-001', '可用', '1001', 'MAT-001', 'PCSN-002', 5, 1, 'UNIT-1', '卷', 'EXT-2', 'TYPE-1', 'DTL-2', FALSE), + (3, 'BOX-002', '不可用', '1001', 'MAT-001', 'PCSN-003', 10, 0, 'UNIT-1', '卷', 'EXT-3', 'TYPE-1', 'DTL-3', FALSE), + (4, 'BOX-003', '可用', '1001', 'MAT-001', 'PCSN-004', 10, 10, 'UNIT-1', '卷', 'EXT-4', 'TYPE-1', 'DTL-4', FALSE), + (5, 'BOX-004', '可用', '1001', 'MAT-001', 'PCSN-005', 10, 0, 'UNIT-1', '卷', 'EXT-5', 'TYPE-1', 'DTL-5', TRUE), + (6, 'BOX-005', '可用', '1001', 'MAT-001', 'PCSN-006', 10, 0, 'UNIT-1', '卷', 'EXT-6', 'TYPE-1', 'DTL-6', FALSE);