PG数据库切换测试用例验证

This commit is contained in:
2026-01-19 14:06:34 +08:00
parent da5648e753
commit ef70728ba0
6 changed files with 1415 additions and 0 deletions

View File

@@ -118,6 +118,18 @@
<version>${org.mapstruct.version}</version>
</dependency>
<!-- Test Dependencies -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>

View File

@@ -0,0 +1,447 @@
package com.sdm.data.dao;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.sdm.data.model.dto.NodeSizeDTO;
import com.sdm.data.model.dto.UserTotalFileSizeDTO;
import com.sdm.data.model.entity.*;
import com.sdm.data.model.req.QueryBigFileReq;
import org.junit.jupiter.api.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.annotation.Rollback;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.List;
import static org.junit.jupiter.api.Assertions.*;
/**
* Mapper层兼容性测试 - MySQL转PostgreSQL验证
* 覆盖所有Mapper接口的基础CRUD和自定义SQL方法
*/
@SpringBootTest
@ActiveProfiles("test")
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
@Transactional
@Rollback(true) // 确保测试后回滚,不污染数据库
public class MapperCompatibilityTest {
@Autowired
private FileStorageMapper fileStorageMapper;
@Autowired
private FileMetadataInfoMapper fileMetadataInfoMapper;
@Autowired
private DimensionTemplateMapper dimensionTemplateMapper;
@Autowired
private DimensionTemplateHierarchyMapper dimensionTemplateHierarchyMapper;
@Autowired
private FileStorageQuotaMapper fileStorageQuotaMapper;
@Autowired
private SimulationParameterLibraryMapper simulationParameterLibraryMapper;
@Autowired
private SimulationParameterLibraryCategoryMapper simulationParameterLibraryCategoryMapper;
@Autowired
private SimulationParameterLibraryCategoryObjectMapper simulationParameterLibraryCategoryObjectMapper;
@Autowired
private TrainingModelMapper trainingModelMapper;
@Autowired
private TrainingModelAlgorithmParamMapper trainingModelAlgorithmParamMapper;
@Autowired
private FileMetadataExtensionMapper fileMetadataExtensionMapper;
@Autowired
private FilePermissionDictMapper filePermissionDictMapper;
@Autowired
private FileUserPermissionMapper fileUserPermissionMapper;
@Autowired
private FileSimulationMappingMapper fileSimulationMappingMapper;
// ==================== FileStorageMapper Tests ====================
@Test
@Order(1)
@DisplayName("FileStorageMapper - 基础CRUD测试")
void testFileStorageMapperCRUD() {
// INSERT
FileStorage entity = new FileStorage();
entity.setFileName("mapper_test.txt");
entity.setFileId(100L);
entity.setTenantId(1L);
entity.setUserId(1L);
entity.setDirId(1L);
entity.setFileSuffix("txt");
entity.setFileBizType(1);
entity.setFileSize(2048L);
entity.setCreateTime(LocalDateTime.now());
entity.setUpdateTime(LocalDateTime.now());
entity.setCreateYearMonth("2026-01");
int insertResult = fileStorageMapper.insert(entity);
assertEquals(1, insertResult);
assertNotNull(entity.getId());
// SELECT BY ID
FileStorage selected = fileStorageMapper.selectById(entity.getId());
assertNotNull(selected);
assertEquals("mapper_test.txt", selected.getFileName());
// UPDATE
selected.setFileName("mapper_test_updated.txt");
selected.setFileSize(4096L);
int updateResult = fileStorageMapper.updateById(selected);
assertEquals(1, updateResult);
// VERIFY UPDATE
FileStorage updated = fileStorageMapper.selectById(entity.getId());
assertEquals("mapper_test_updated.txt", updated.getFileName());
assertEquals(4096L, updated.getFileSize());
// DELETE
int deleteResult = fileStorageMapper.deleteById(entity.getId());
assertEquals(1, deleteResult);
// VERIFY DELETE
FileStorage deleted = fileStorageMapper.selectById(entity.getId());
assertNull(deleted);
}
@Test
@Order(2)
@DisplayName("FileStorageMapper - selectNodeSizeByNodeType自定义SQL测试")
void testFileStorageMapperSelectNodeSizeByNodeType() {
List<NodeSizeDTO> result = fileStorageMapper.selectNodeSizeByNodeType(
Arrays.asList(1L, 2L, 3L),
3,
1L
);
assertNotNull(result);
// 验证SQL执行不报错结果可能为空但不应该抛异常
}
@Test
@Order(3)
@DisplayName("FileStorageMapper - statDirStorageByTargetYm自定义SQL测试")
void testFileStorageMapperStatDirStorageByTargetYm() {
List<NodeSizeDTO> result = fileStorageMapper.statDirStorageByTargetYm(
Arrays.asList(1L, 2L),
"2026-01",
1L
);
assertNotNull(result);
}
@Test
@Order(4)
@DisplayName("FileStorageMapper - getTotalFileSizeByCreator自定义SQL测试")
void testFileStorageMapperGetTotalFileSizeByCreator() {
List<UserTotalFileSizeDTO> result = fileStorageMapper.getTotalFileSizeByCreator(
Arrays.asList(1L),
6,
1L
);
assertNotNull(result);
}
@Test
@Order(5)
@DisplayName("FileStorageMapper - getTotalFileSizeByCreatorAndTargetYm自定义SQL测试")
void testFileStorageMapperGetTotalFileSizeByCreatorAndTargetYm() {
List<UserTotalFileSizeDTO> result = fileStorageMapper.getTotalFileSizeByCreatorAndTargetYm(
Arrays.asList(1L),
"2026-01",
1L
);
assertNotNull(result);
}
@Test
@Order(6)
@DisplayName("FileStorageMapper - selectBigFiles自定义SQL测试")
void testFileStorageMapperSelectBigFiles() {
QueryBigFileReq req = new QueryBigFileReq();
req.setIsLatest(true);
req.setDirIds(Arrays.asList(1L));
List<FileStorage> result = fileStorageMapper.selectBigFiles(req, 1000L, 1L);
assertNotNull(result);
}
// ==================== FileMetadataInfoMapper Tests ====================
@Test
@Order(10)
@DisplayName("FileMetadataInfoMapper - 基础CRUD测试")
void testFileMetadataInfoMapperCRUD() {
// INSERT
FileMetadataInfo entity = new FileMetadataInfo();
entity.setRelatedResourceUuid("test-uuid-mapper");
entity.setRelatedResourceUuidOwnType("node");
entity.setOriginalName("mapper_metadata.txt");
entity.setDataType(2);
entity.setIsLatest(true);
entity.setTenantId(1L);
entity.setCreatorId(1L);
entity.setCreateTime(LocalDateTime.now());
entity.setUpdateTime(LocalDateTime.now());
int insertResult = fileMetadataInfoMapper.insert(entity);
assertEquals(1, insertResult);
assertNotNull(entity.getId());
// SELECT
FileMetadataInfo selected = fileMetadataInfoMapper.selectById(entity.getId());
assertNotNull(selected);
assertEquals("mapper_metadata.txt", selected.getOriginalName());
// UPDATE
selected.setOriginalName("mapper_metadata_updated.txt");
fileMetadataInfoMapper.updateById(selected);
// DELETE
fileMetadataInfoMapper.deleteById(entity.getId());
}
@Test
@Order(11)
@DisplayName("FileMetadataInfoMapper - listSimulationNodeDir自定义SQL测试")
void testFileMetadataInfoMapperListSimulationNodeDir() {
List<FileMetadataInfo> result = fileMetadataInfoMapper.listSimulationNodeDir(
Arrays.asList(1L, 2L),
false,
1L
);
assertNotNull(result);
}
@Test
@Order(12)
@DisplayName("FileMetadataInfoMapper - listSimulationNodeFiles自定义SQL测试")
void testFileMetadataInfoMapperListSimulationNodeFiles() {
List<FileMetadataInfo> result = fileMetadataInfoMapper.listSimulationNodeFiles(
Arrays.asList(1L),
Arrays.asList(1L),
false,
1L
);
assertNotNull(result);
}
// ==================== DimensionTemplateMapper Tests ====================
@Test
@Order(20)
@DisplayName("DimensionTemplateMapper - 基础CRUD测试")
void testDimensionTemplateMapperCRUD() {
// INSERT
DimensionTemplate entity = new DimensionTemplate();
entity.setTemplateName("Mapper测试模板");
entity.setTemplateType(1);
entity.setDescription("用于Mapper测试");
entity.setTenantId(1L);
entity.setCreatedBy(1L);
entity.setCreatedAt(LocalDateTime.now());
int insertResult = dimensionTemplateMapper.insert(entity);
assertEquals(1, insertResult);
// SELECT
DimensionTemplate selected = dimensionTemplateMapper.selectById(entity.getId());
assertNotNull(selected);
assertEquals("Mapper测试模板", selected.getTemplateName());
// UPDATE & DELETE
selected.setTemplateName("Mapper测试模板_更新");
dimensionTemplateMapper.updateById(selected);
dimensionTemplateMapper.deleteById(entity.getId());
}
// ==================== FileStorageQuotaMapper Tests ====================
@Test
@Order(30)
@DisplayName("FileStorageQuotaMapper - 基础CRUD测试")
void testFileStorageQuotaMapperCRUD() {
// INSERT
FileStorageQuota entity = new FileStorageQuota();
entity.setUserId(100L);
entity.setTenantId(1L);
entity.setQuotaValue(5368709120L); // 5GB
entity.setQuotaUnit("GB");
entity.setUsedValue(0L);
entity.setStatus("NORMAL");
int insertResult = fileStorageQuotaMapper.insert(entity);
assertEquals(1, insertResult);
// SELECT
FileStorageQuota selected = fileStorageQuotaMapper.selectById(entity.getId());
assertNotNull(selected);
assertEquals("GB", selected.getQuotaUnit());
// UPDATE & DELETE
selected.setStatus("WARNING");
fileStorageQuotaMapper.updateById(selected);
fileStorageQuotaMapper.deleteById(entity.getId());
}
// ==================== SimulationParameterLibraryMapper Tests ====================
@Test
@Order(40)
@DisplayName("SimulationParameterLibraryMapper - 基础CRUD测试")
void testSimulationParameterLibraryMapperCRUD() {
// INSERT
SimulationParameterLibrary entity = new SimulationParameterLibrary();
entity.setParameterLibraryName("Mapper测试参数库");
entity.setTenantId(1L);
entity.setCreatorId(1L);
entity.setCreateTime(LocalDateTime.now());
int insertResult = simulationParameterLibraryMapper.insert(entity);
assertEquals(1, insertResult);
// SELECT
SimulationParameterLibrary selected = simulationParameterLibraryMapper.selectById(entity.getId());
assertNotNull(selected);
// DELETE
simulationParameterLibraryMapper.deleteById(entity.getId());
}
// ==================== TrainingModelMapper Tests ====================
@Test
@Order(50)
@DisplayName("TrainingModelMapper - 基础CRUD测试")
void testTrainingModelMapperCRUD() {
// INSERT
TrainingModel entity = new TrainingModel();
entity.setModelName("Mapper测试模型");
entity.setAlgorithmType("SVM");
entity.setTrainer("tester");
entity.setHandleStatus("待开始");
entity.setTrainingStatus("待开始");
entity.setPredStatus("待开始");
entity.setTenantId(1L);
entity.setCreator(1L);
entity.setCreateTime(LocalDateTime.now());
int insertResult = trainingModelMapper.insert(entity);
assertEquals(1, insertResult);
// SELECT
TrainingModel selected = trainingModelMapper.selectById(entity.getId());
assertNotNull(selected);
assertEquals("Mapper测试模型", selected.getModelName());
// UPDATE & DELETE
selected.setModelName("Mapper测试模型_更新");
trainingModelMapper.updateById(selected);
trainingModelMapper.deleteById(entity.getId());
}
// ==================== 条件查询测试 ====================
@Test
@Order(60)
@DisplayName("LambdaQueryWrapper条件查询测试")
void testLambdaQueryWrapper() {
// 测试MyBatis-Plus的LambdaQueryWrapper在PostgreSQL下的兼容性
LambdaQueryWrapper<FileStorage> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(FileStorage::getTenantId, 1L)
.like(FileStorage::getFileName, "test")
.orderByDesc(FileStorage::getCreateTime);
List<FileStorage> result = fileStorageMapper.selectList(wrapper);
assertNotNull(result);
}
@Test
@Order(61)
@DisplayName("批量查询测试")
void testBatchSelect() {
List<FileStorage> result = fileStorageMapper.selectBatchIds(Arrays.asList(1L, 2L, 3L));
assertNotNull(result);
}
// ==================== 其他Mapper基础测试 ====================
@Test
@Order(70)
@DisplayName("FileMetadataExtensionMapper - 基础测试")
void testFileMetadataExtensionMapper() {
List<FileMetadataExtension> result = fileMetadataExtensionMapper.selectList(null);
assertNotNull(result);
}
@Test
@Order(71)
@DisplayName("FilePermissionDictMapper - 基础测试")
void testFilePermissionDictMapper() {
List<FilePermissionDict> result = filePermissionDictMapper.selectList(null);
assertNotNull(result);
}
@Test
@Order(72)
@DisplayName("FileUserPermissionMapper - 基础测试")
void testFileUserPermissionMapper() {
List<FileUserPermission> result = fileUserPermissionMapper.selectList(null);
assertNotNull(result);
}
@Test
@Order(73)
@DisplayName("FileSimulationMappingMapper - 基础测试")
void testFileSimulationMappingMapper() {
List<FileSimulationMapping> result = fileSimulationMappingMapper.selectList(null);
assertNotNull(result);
}
@Test
@Order(74)
@DisplayName("DimensionTemplateHierarchyMapper - 基础测试")
void testDimensionTemplateHierarchyMapper() {
List<DimensionTemplateHierarchy> result = dimensionTemplateHierarchyMapper.selectList(null);
assertNotNull(result);
}
@Test
@Order(75)
@DisplayName("SimulationParameterLibraryCategoryMapper - 基础测试")
void testSimulationParameterLibraryCategoryMapper() {
List<SimulationParameterLibraryCategory> result = simulationParameterLibraryCategoryMapper.selectList(null);
assertNotNull(result);
}
@Test
@Order(76)
@DisplayName("SimulationParameterLibraryCategoryObjectMapper - 基础测试")
void testSimulationParameterLibraryCategoryObjectMapper() {
List<SimulationParameterLibraryCategoryObject> result = simulationParameterLibraryCategoryObjectMapper.selectList(null);
assertNotNull(result);
}
@Test
@Order(77)
@DisplayName("TrainingModelAlgorithmParamMapper - 基础测试")
void testTrainingModelAlgorithmParamMapper() {
List<TrainingModelAlgorithmParam> result = trainingModelAlgorithmParamMapper.selectList(null);
assertNotNull(result);
}
}

View File

@@ -0,0 +1,351 @@
package com.sdm.data.dao;
import com.sdm.data.model.dto.NodeSizeDTO;
import com.sdm.data.model.dto.UserTotalFileSizeDTO;
import com.sdm.data.model.entity.FileMetadataInfo;
import com.sdm.data.model.entity.FileStorage;
import com.sdm.data.model.req.QueryBigFileReq;
import org.junit.jupiter.api.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.annotation.Rollback;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import static org.junit.jupiter.api.Assertions.*;
/**
* PostgreSQL SQL语法兼容性专项测试
*
* 重点验证以下MySQL到PostgreSQL的语法差异
* 1. DATE_SUB函数 -> PostgreSQL的INTERVAL语法
* 2. LIMIT在UNION中的使用
* 3. CONCAT函数
* 4. Boolean字段处理
* 5. 字段名大小写敏感性
*/
@SpringBootTest
@ActiveProfiles("test")
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
@Transactional
@Rollback(true) // 确保测试后回滚,不污染数据库
public class PostgreSQLCompatibilityTest {
@Autowired
private FileStorageMapper fileStorageMapper;
@Autowired
private FileMetadataInfoMapper fileMetadataInfoMapper;
// ==================== DATE_SUB/INTERVAL 语法测试 ====================
@Test
@Order(1)
@DisplayName("测试时间间隔查询 - selectNodeSizeByNodeType (MySQL: DATE_SUB)")
void testDateIntervalQuery() {
// 准备测试数据
FileStorage entity = createTestFileStorage("interval_test.txt");
entity.setCreateTime(LocalDateTime.now().minusMonths(1)); // 1个月前
fileStorageMapper.insert(entity);
// 测试3个月内的数据查询
List<NodeSizeDTO> result = fileStorageMapper.selectNodeSizeByNodeType(
Arrays.asList(entity.getDirId()),
3, // 3个月
1L
);
assertNotNull(result);
// 验证能够查询到1个月前的数据
}
@Test
@Order(2)
@DisplayName("测试时间间隔查询 - getTotalFileSizeByCreator (MySQL: DATE_SUB)")
void testDateIntervalQueryForUser() {
// 测试用户文件大小统计的时间间隔查询
List<UserTotalFileSizeDTO> result = fileStorageMapper.getTotalFileSizeByCreator(
Arrays.asList(1L),
6, // 6个月
1L
);
assertNotNull(result);
}
// ==================== UNION ALL + LIMIT 语法测试 ====================
@Test
@Order(10)
@DisplayName("测试UNION ALL查询 - statDirStorageByTargetYm")
void testUnionAllQuery() {
// 准备不同月份的测试数据
FileStorage entity1 = createTestFileStorage("union_test_1.txt");
entity1.setCreateYearMonth("2026-01");
fileStorageMapper.insert(entity1);
FileStorage entity2 = createTestFileStorage("union_test_2.txt");
entity2.setCreateYearMonth("2025-12");
fileStorageMapper.insert(entity2);
// 测试UNION ALL查询历史累计 + 当月增量)
List<NodeSizeDTO> result = fileStorageMapper.statDirStorageByTargetYm(
Arrays.asList(entity1.getDirId()),
"2026-01",
1L
);
assertNotNull(result);
// 应该返回BEFORE和INCREMENT两种类型的统计
}
@Test
@Order(11)
@DisplayName("测试带LIMIT的UNION查询 - getTotalFileSizeByCreatorAndTargetYm (CTE)")
void testUnionWithLimitAndCTE() {
// 测试使用CTE(WITH)的复杂查询
List<UserTotalFileSizeDTO> result = fileStorageMapper.getTotalFileSizeByCreatorAndTargetYm(
null, // 不传userIds测试LIMIT 10的分支
"2026-01",
1L
);
assertNotNull(result);
}
@Test
@Order(12)
@DisplayName("测试带LIMIT的查询 - getdefaultNodeNameByNodeSize")
void testLimitQuery() {
List<String> result = fileStorageMapper.getdefaultNodeNameByNodeSize(
"node",
5 // LIMIT 5
);
assertNotNull(result);
assertTrue(result.size() <= 5);
}
// ==================== CONCAT 函数测试 ====================
@Test
@Order(20)
@DisplayName("测试CONCAT函数 - selectBigFiles的LIKE查询")
void testConcatInLikeQuery() {
// 准备测试数据
FileStorage fileStorage = createTestFileStorage("concat_test_file.txt");
fileStorageMapper.insert(fileStorage);
FileMetadataInfo metadata = new FileMetadataInfo();
metadata.setId(fileStorage.getFileId());
metadata.setOriginalName("concat_test_file.txt");
metadata.setIsLatest(true);
metadata.setTenantId(1L);
metadata.setDataType(2);
metadata.setApproveType(0);
metadata.setCreateTime(LocalDateTime.now());
metadata.setUpdateTime(LocalDateTime.now());
fileMetadataInfoMapper.insert(metadata);
// 测试CONCAT在LIKE中的使用
QueryBigFileReq req = new QueryBigFileReq();
req.setIsLatest(true);
req.setFileName("concat"); // 模糊匹配
List<FileStorage> result = fileStorageMapper.selectBigFiles(req, 0L, 1L);
assertNotNull(result);
}
// ==================== Boolean 字段测试 ====================
@Test
@Order(30)
@DisplayName("测试Boolean字段 - isLatest = true")
void testBooleanField() {
// 测试PostgreSQL的Boolean类型处理
FileMetadataInfo entityTrue = new FileMetadataInfo();
entityTrue.setOriginalName("boolean_true.txt");
entityTrue.setIsLatest(true);
entityTrue.setIsRoot(false);
entityTrue.setTenantId(1L);
entityTrue.setDataType(2);
entityTrue.setCreateTime(LocalDateTime.now());
entityTrue.setUpdateTime(LocalDateTime.now());
fileMetadataInfoMapper.insert(entityTrue);
FileMetadataInfo entityFalse = new FileMetadataInfo();
entityFalse.setOriginalName("boolean_false.txt");
entityFalse.setIsLatest(false);
entityFalse.setIsRoot(true);
entityFalse.setTenantId(1L);
entityFalse.setDataType(2);
entityFalse.setCreateTime(LocalDateTime.now());
entityFalse.setUpdateTime(LocalDateTime.now());
fileMetadataInfoMapper.insert(entityFalse);
// 测试listSimulationNodeFiles中的 isLatest = true
List<FileMetadataInfo> result = fileMetadataInfoMapper.listSimulationNodeFiles(
Arrays.asList(entityTrue.getParentId() != null ? entityTrue.getParentId() : 0L),
Collections.emptyList(),
false,
1L
);
assertNotNull(result);
}
// ==================== 字段名大小写敏感性测试 ====================
@Test
@Order(40)
@DisplayName("测试驼峰字段名映射 - fileName/fileSize等")
void testCamelCaseFieldMapping() {
FileStorage entity = new FileStorage();
entity.setFileName("camelCase_test.txt");
entity.setFileId(System.currentTimeMillis());
entity.setFileSize(2048L);
entity.setFileBizType(1);
entity.setFileSuffix("txt");
entity.setTenantId(1L);
entity.setUserId(1L);
entity.setDirId(1L);
entity.setCreateYearMonth("2026-01");
entity.setCreateTime(LocalDateTime.now());
entity.setUpdateTime(LocalDateTime.now());
entity.setFullPath("/test/camelCase_test.txt");
// 插入
int insertResult = fileStorageMapper.insert(entity);
assertEquals(1, insertResult);
// 查询并验证所有驼峰命名字段
FileStorage selected = fileStorageMapper.selectById(entity.getId());
assertNotNull(selected);
assertEquals("camelCase_test.txt", selected.getFileName());
assertEquals(2048L, selected.getFileSize());
assertEquals(1, selected.getFileBizType());
assertEquals("txt", selected.getFileSuffix());
assertEquals("2026-01", selected.getCreateYearMonth());
assertEquals("/test/camelCase_test.txt", selected.getFullPath());
}
// ==================== NULL值处理测试 ====================
@Test
@Order(50)
@DisplayName("测试NULL值条件查询")
void testNullConditionQuery() {
// 测试IS NULL查询
List<FileMetadataInfo> result = fileMetadataInfoMapper.listSimulationNodeDir(
Arrays.asList(1L),
false, // 不过滤空数据
1L
);
assertNotNull(result);
}
// ==================== 空集合参数测试 ====================
@Test
@Order(60)
@DisplayName("测试空集合参数处理")
void testEmptyCollectionParameter() {
// 测试传入空列表时的处理
List<UserTotalFileSizeDTO> result = fileStorageMapper.getTotalFileSizeByCreator(
Collections.emptyList(), // 空列表
6,
1L
);
assertNotNull(result);
// 应该返回前10个用户根据SQL逻辑
}
// ==================== ORDER BY 测试 ====================
@Test
@Order(70)
@DisplayName("测试ORDER BY子句")
void testOrderByClause() {
// 准备多条测试数据
for (int i = 1; i <= 3; i++) {
FileStorage entity = createTestFileStorage("order_test_" + i + ".txt");
entity.setFileSize(i * 1000L);
entity.setUpdateTime(LocalDateTime.now().minusHours(i));
fileStorageMapper.insert(entity);
}
// 测试selectBigFiles中的ORDER BY updateTime DESC
QueryBigFileReq req = new QueryBigFileReq();
req.setIsLatest(true);
req.setFileName("order_test");
List<FileStorage> result = fileStorageMapper.selectBigFiles(req, 0L, 1L);
assertNotNull(result);
// 验证是否按updateTime降序排列
if (result.size() >= 2) {
assertTrue(
result.get(0).getUpdateTime().isAfter(result.get(1).getUpdateTime()) ||
result.get(0).getUpdateTime().isEqual(result.get(1).getUpdateTime())
);
}
}
// ==================== 聚合函数测试 ====================
@Test
@Order(80)
@DisplayName("测试SUM聚合函数")
void testSumAggregation() {
// 准备测试数据
Long testDirId = 99999L;
FileStorage entity1 = createTestFileStorage("sum_test_1.txt");
entity1.setDirId(testDirId);
entity1.setFileSize(1000L);
fileStorageMapper.insert(entity1);
FileStorage entity2 = createTestFileStorage("sum_test_2.txt");
entity2.setDirId(testDirId);
entity2.setFileSize(2000L);
fileStorageMapper.insert(entity2);
// 测试SUM聚合
List<NodeSizeDTO> result = fileStorageMapper.selectNodeSizeByNodeType(
Arrays.asList(testDirId),
12,
1L
);
assertNotNull(result);
if (!result.isEmpty()) {
// 验证总大小 = 1000 + 2000 = 3000
assertEquals(3000L, result.get(0).getTotalSize());
}
}
// ==================== Helper Methods ====================
private FileStorage createTestFileStorage(String fileName) {
FileStorage entity = new FileStorage();
entity.setFileName(fileName);
entity.setFileId(System.currentTimeMillis());
entity.setTenantId(1L);
entity.setUserId(1L);
entity.setDirId(1L);
entity.setFileSuffix("txt");
entity.setFileBizType(1);
entity.setFileSize(1024L);
entity.setCreateTime(LocalDateTime.now());
entity.setUpdateTime(LocalDateTime.now());
entity.setCreateYearMonth("2026-01");
return entity;
}
}

View File

@@ -0,0 +1,517 @@
package com.sdm.data.service;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.sdm.data.model.entity.*;
import org.junit.jupiter.api.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.annotation.Rollback;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.List;
import static org.junit.jupiter.api.Assertions.*;
/**
* Service层CRUD测试 - MySQL转PostgreSQL验证
* 覆盖所有Service的基础CRUD操作
*/
@SpringBootTest
@ActiveProfiles("test")
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
@Transactional
@Rollback(true) // 确保测试后回滚,不污染数据库
public class ServiceCrudTest {
@Autowired
private IFileStorageService fileStorageService;
@Autowired
private IFileMetadataInfoService fileMetadataInfoService;
@Autowired
private IDimensionTemplateService dimensionTemplateService;
@Autowired
private IFileStorageQuotaService fileStorageQuotaService;
@Autowired
private ISimulationParameterLibraryService simulationParameterLibraryService;
@Autowired
private ITrainingModelService trainingModelService;
@Autowired
private IFileMetadataExtensionService fileMetadataExtensionService;
@Autowired
private IFileSimulationMappingService fileSimulationMappingService;
@Autowired
private IFileUserPermissionService fileUserPermissionService;
@Autowired
private IDimensionTemplateHierarchyService dimensionTemplateHierarchyService;
@Autowired
private ISimulationParameterLibraryCategoryService simulationParameterLibraryCategoryService;
@Autowired
private ISimulationParameterLibraryCategoryObjectService simulationParameterLibraryCategoryObjectService;
@Autowired
private ITrainingModelAlgorithmParamService trainingModelAlgorithmParamService;
// ==================== IFileStorageService Tests ====================
@Test
@Order(1)
@DisplayName("IFileStorageService - save保存测试")
void testFileStorageServiceSave() {
FileStorage entity = createFileStorageEntity("service_test.txt");
boolean result = fileStorageService.save(entity);
assertTrue(result);
assertNotNull(entity.getId());
}
@Test
@Order(2)
@DisplayName("IFileStorageService - getById查询测试")
void testFileStorageServiceGetById() {
// 先插入
FileStorage entity = createFileStorageEntity("service_get_test.txt");
fileStorageService.save(entity);
// 再查询
FileStorage result = fileStorageService.getById(entity.getId());
assertNotNull(result);
assertEquals("service_get_test.txt", result.getFileName());
}
@Test
@Order(3)
@DisplayName("IFileStorageService - updateById更新测试")
void testFileStorageServiceUpdate() {
FileStorage entity = createFileStorageEntity("service_update_test.txt");
fileStorageService.save(entity);
entity.setFileName("service_update_test_modified.txt");
entity.setFileSize(8192L);
boolean result = fileStorageService.updateById(entity);
assertTrue(result);
FileStorage updated = fileStorageService.getById(entity.getId());
assertEquals("service_update_test_modified.txt", updated.getFileName());
assertEquals(8192L, updated.getFileSize());
}
@Test
@Order(4)
@DisplayName("IFileStorageService - removeById删除测试")
void testFileStorageServiceRemove() {
FileStorage entity = createFileStorageEntity("service_remove_test.txt");
fileStorageService.save(entity);
boolean result = fileStorageService.removeById(entity.getId());
assertTrue(result);
assertNull(fileStorageService.getById(entity.getId()));
}
@Test
@Order(5)
@DisplayName("IFileStorageService - list列表查询测试")
void testFileStorageServiceList() {
List<FileStorage> result = fileStorageService.list();
assertNotNull(result);
}
@Test
@Order(6)
@DisplayName("IFileStorageService - 条件查询测试")
void testFileStorageServiceListWithWrapper() {
FileStorage entity = createFileStorageEntity("service_wrapper_test.txt");
entity.setFileBizType(99);
fileStorageService.save(entity);
LambdaQueryWrapper<FileStorage> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(FileStorage::getFileBizType, 99);
List<FileStorage> result = fileStorageService.list(wrapper);
assertNotNull(result);
assertFalse(result.isEmpty());
}
@Test
@Order(7)
@DisplayName("IFileStorageService - 分页查询测试")
void testFileStorageServicePage() {
Page<FileStorage> page = new Page<>(1, 10);
Page<FileStorage> result = fileStorageService.page(page);
assertNotNull(result);
assertNotNull(result.getRecords());
}
@Test
@Order(8)
@DisplayName("IFileStorageService - 批量保存测试")
void testFileStorageServiceSaveBatch() {
List<FileStorage> entities = Arrays.asList(
createFileStorageEntity("batch_1.txt"),
createFileStorageEntity("batch_2.txt"),
createFileStorageEntity("batch_3.txt")
);
boolean result = fileStorageService.saveBatch(entities);
assertTrue(result);
entities.forEach(e -> assertNotNull(e.getId()));
}
@Test
@Order(9)
@DisplayName("IFileStorageService - 自定义方法selectNodeSizeByNodeType测试")
void testFileStorageServiceSelectNodeSizeByNodeType() {
var result = fileStorageService.selectNodeSizeByNodeType(
Arrays.asList(1L, 2L),
3,
1L
);
assertNotNull(result);
}
// ==================== IFileMetadataInfoService Tests ====================
@Test
@Order(20)
@DisplayName("IFileMetadataInfoService - CRUD完整测试")
void testFileMetadataInfoServiceCRUD() {
// CREATE
FileMetadataInfo entity = createFileMetadataInfoEntity("service_metadata.txt");
boolean saveResult = fileMetadataInfoService.save(entity);
assertTrue(saveResult);
// READ
FileMetadataInfo read = fileMetadataInfoService.getById(entity.getId());
assertNotNull(read);
// UPDATE
read.setOriginalName("service_metadata_updated.txt");
boolean updateResult = fileMetadataInfoService.updateById(read);
assertTrue(updateResult);
// DELETE
boolean deleteResult = fileMetadataInfoService.removeById(entity.getId());
assertTrue(deleteResult);
}
@Test
@Order(21)
@DisplayName("IFileMetadataInfoService - listSimulationNodeDir测试")
void testFileMetadataInfoServiceListSimulationNodeDir() {
var result = fileMetadataInfoService.listSimulationNodeDir(
Arrays.asList(1L, 2L),
false,
1L
);
assertNotNull(result);
}
// ==================== IDimensionTemplateService Tests ====================
@Test
@Order(30)
@DisplayName("IDimensionTemplateService - CRUD完整测试")
void testDimensionTemplateServiceCRUD() {
// CREATE
DimensionTemplate entity = createDimensionTemplateEntity("Service测试模板");
boolean saveResult = dimensionTemplateService.save(entity);
assertTrue(saveResult);
// READ
DimensionTemplate read = dimensionTemplateService.getById(entity.getId());
assertNotNull(read);
assertEquals("Service测试模板", read.getTemplateName());
// UPDATE
read.setTemplateName("Service测试模板_更新");
boolean updateResult = dimensionTemplateService.updateById(read);
assertTrue(updateResult);
// DELETE
boolean deleteResult = dimensionTemplateService.removeById(entity.getId());
assertTrue(deleteResult);
}
// ==================== IFileStorageQuotaService Tests ====================
@Test
@Order(40)
@DisplayName("IFileStorageQuotaService - CRUD完整测试")
void testFileStorageQuotaServiceCRUD() {
// CREATE
FileStorageQuota entity = createFileStorageQuotaEntity(200L);
boolean saveResult = fileStorageQuotaService.save(entity);
assertTrue(saveResult);
// READ
FileStorageQuota read = fileStorageQuotaService.getById(entity.getId());
assertNotNull(read);
// UPDATE
read.setStatus("WARNING");
boolean updateResult = fileStorageQuotaService.updateById(read);
assertTrue(updateResult);
// DELETE
boolean deleteResult = fileStorageQuotaService.removeById(entity.getId());
assertTrue(deleteResult);
}
// ==================== ISimulationParameterLibraryService Tests ====================
@Test
@Order(50)
@DisplayName("ISimulationParameterLibraryService - CRUD完整测试")
void testSimulationParameterLibraryServiceCRUD() {
// CREATE
SimulationParameterLibrary entity = createSimulationParameterLibraryEntity("Service测试参数库");
boolean saveResult = simulationParameterLibraryService.save(entity);
assertTrue(saveResult);
// READ
SimulationParameterLibrary read = simulationParameterLibraryService.getById(entity.getId());
assertNotNull(read);
// UPDATE
read.setParameterLibraryName("Service测试参数库_更新");
boolean updateResult = simulationParameterLibraryService.updateById(read);
assertTrue(updateResult);
// DELETE
boolean deleteResult = simulationParameterLibraryService.removeById(entity.getId());
assertTrue(deleteResult);
}
// ==================== ITrainingModelService Tests ====================
@Test
@Order(60)
@DisplayName("ITrainingModelService - CRUD完整测试")
void testTrainingModelServiceCRUD() {
// CREATE
TrainingModel entity = createTrainingModelEntity("Service测试模型");
boolean saveResult = trainingModelService.save(entity);
assertTrue(saveResult);
// READ
TrainingModel read = trainingModelService.getById(entity.getId());
assertNotNull(read);
assertEquals("Service测试模型", read.getModelName());
// UPDATE
read.setModelName("Service测试模型_更新");
boolean updateResult = trainingModelService.updateById(read);
assertTrue(updateResult);
// DELETE
boolean deleteResult = trainingModelService.removeById(entity.getId());
assertTrue(deleteResult);
}
// ==================== 其他Service基础CRUD测试 ====================
@Test
@Order(70)
@DisplayName("IFileMetadataExtensionService - 基础测试")
void testFileMetadataExtensionService() {
List<FileMetadataExtension> result = fileMetadataExtensionService.list();
assertNotNull(result);
}
@Test
@Order(71)
@DisplayName("IFileSimulationMappingService - 基础测试")
void testFileSimulationMappingService() {
List<FileSimulationMapping> result = fileSimulationMappingService.list();
assertNotNull(result);
}
@Test
@Order(72)
@DisplayName("IFileUserPermissionService - 基础测试")
void testFileUserPermissionService() {
List<FileUserPermission> result = fileUserPermissionService.list();
assertNotNull(result);
}
@Test
@Order(73)
@DisplayName("IDimensionTemplateHierarchyService - 基础测试")
void testDimensionTemplateHierarchyService() {
List<DimensionTemplateHierarchy> result = dimensionTemplateHierarchyService.list();
assertNotNull(result);
}
@Test
@Order(74)
@DisplayName("ISimulationParameterLibraryCategoryService - 基础测试")
void testSimulationParameterLibraryCategoryService() {
List<SimulationParameterLibraryCategory> result = simulationParameterLibraryCategoryService.list();
assertNotNull(result);
}
@Test
@Order(75)
@DisplayName("ISimulationParameterLibraryCategoryObjectService - 基础测试")
void testSimulationParameterLibraryCategoryObjectService() {
List<SimulationParameterLibraryCategoryObject> result = simulationParameterLibraryCategoryObjectService.list();
assertNotNull(result);
}
@Test
@Order(76)
@DisplayName("ITrainingModelAlgorithmParamService - 基础测试")
void testTrainingModelAlgorithmParamService() {
List<TrainingModelAlgorithmParam> result = trainingModelAlgorithmParamService.list();
assertNotNull(result);
}
// ==================== 复杂查询测试 ====================
@Test
@Order(80)
@DisplayName("复杂条件组合查询测试")
void testComplexQuery() {
// 准备测试数据
FileStorage entity1 = createFileStorageEntity("complex_1.txt");
entity1.setFileBizType(100);
entity1.setFileSize(1000L);
fileStorageService.save(entity1);
FileStorage entity2 = createFileStorageEntity("complex_2.txt");
entity2.setFileBizType(100);
entity2.setFileSize(2000L);
fileStorageService.save(entity2);
// 复杂查询
LambdaQueryWrapper<FileStorage> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(FileStorage::getFileBizType, 100)
.ge(FileStorage::getFileSize, 1000L)
.orderByDesc(FileStorage::getFileSize);
List<FileStorage> result = fileStorageService.list(wrapper);
assertNotNull(result);
assertEquals(2, result.size());
// 验证排序
assertTrue(result.get(0).getFileSize() >= result.get(1).getFileSize());
}
@Test
@Order(81)
@DisplayName("统计count测试")
void testCount() {
long count = fileStorageService.count();
assertTrue(count >= 0);
}
@Test
@Order(82)
@DisplayName("条件统计count测试")
void testCountWithWrapper() {
LambdaQueryWrapper<FileStorage> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(FileStorage::getTenantId, 1L);
long count = fileStorageService.count(wrapper);
assertTrue(count >= 0);
}
// ==================== Helper Methods ====================
private FileStorage createFileStorageEntity(String fileName) {
FileStorage entity = new FileStorage();
entity.setFileName(fileName);
entity.setFileId(System.currentTimeMillis());
entity.setTenantId(1L);
entity.setUserId(1L);
entity.setDirId(1L);
entity.setFileSuffix("txt");
entity.setFileBizType(1);
entity.setFileSize(1024L);
entity.setCreateTime(LocalDateTime.now());
entity.setUpdateTime(LocalDateTime.now());
entity.setCreateYearMonth("2026-01");
return entity;
}
private FileMetadataInfo createFileMetadataInfoEntity(String originalName) {
FileMetadataInfo entity = new FileMetadataInfo();
entity.setRelatedResourceUuid("uuid-" + System.currentTimeMillis());
entity.setRelatedResourceUuidOwnType("node");
entity.setOriginalName(originalName);
entity.setDataType(2);
entity.setIsLatest(true);
entity.setTenantId(1L);
entity.setCreatorId(1L);
entity.setCreateTime(LocalDateTime.now());
entity.setUpdateTime(LocalDateTime.now());
return entity;
}
private DimensionTemplate createDimensionTemplateEntity(String templateName) {
DimensionTemplate entity = new DimensionTemplate();
entity.setTemplateName(templateName);
entity.setTemplateType(1);
entity.setDescription("测试描述");
entity.setTenantId(1L);
entity.setCreatedBy(1L);
entity.setCreatedAt(LocalDateTime.now());
return entity;
}
private FileStorageQuota createFileStorageQuotaEntity(Long userId) {
FileStorageQuota entity = new FileStorageQuota();
entity.setUserId(userId);
entity.setTenantId(1L);
entity.setQuotaValue(5368709120L);
entity.setQuotaUnit("GB");
entity.setUsedValue(0L);
entity.setStatus("NORMAL");
return entity;
}
private SimulationParameterLibrary createSimulationParameterLibraryEntity(String name) {
SimulationParameterLibrary entity = new SimulationParameterLibrary();
entity.setParameterLibraryName(name);
entity.setTenantId(1L);
entity.setCreatorId(1L);
entity.setCreateTime(LocalDateTime.now());
return entity;
}
private TrainingModel createTrainingModelEntity(String modelName) {
TrainingModel entity = new TrainingModel();
entity.setModelName(modelName);
entity.setAlgorithmType("SVM");
entity.setTrainer("tester");
entity.setHandleStatus("待开始");
entity.setTrainingStatus("待开始");
entity.setPredStatus("待开始");
entity.setTenantId(1L);
entity.setCreator(1L);
entity.setCreateTime(LocalDateTime.now());
return entity;
}
}

View File

@@ -0,0 +1,28 @@
spring:
datasource:
# 直接连接PostgreSQL数据库进行单元测试
url: jdbc:postgresql://192.168.65.161:25432/spdm?currentSchema=public&stringtype=unspecified
driver-class-name: org.postgresql.Driver
username: spdm
password: Spdm@2026
hikari:
maximum-pool-size: 5
minimum-idle: 2
connection-timeout: 30000
mybatis-plus:
mapper-locations: classpath*:/mapper/**/*.xml
configuration:
map-underscore-to-camel-case: false
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
global-config:
db-config:
id-type: auto
logic-delete-value: 1
logic-not-delete-value: 0
logging:
level:
com.sdm.data: DEBUG
org.springframework.jdbc: DEBUG
org.apache.ibatis: DEBUG