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);