From 5a18d863778ffabcc45da185f7f77e7462289bb9 Mon Sep 17 00:00:00 2001
From: yeg <1347747024@qq.com>
Date: 星期四, 27 八月 2026 20:45:31 +0800
Subject: [PATCH] feat(test): implement test configuration and channel binding
---
ruoyi-admin/src/test/java/com/ruoyi/system/service/impl/TTestServiceImplTest.java | 275 +++++++++++++++++++++++++++++++++++++-----------------
1 files changed, 188 insertions(+), 87 deletions(-)
diff --git a/ruoyi-admin/src/test/java/com/ruoyi/system/service/impl/TTestServiceImplTest.java b/ruoyi-admin/src/test/java/com/ruoyi/system/service/impl/TTestServiceImplTest.java
index b96b26b..71aa715 100644
--- a/ruoyi-admin/src/test/java/com/ruoyi/system/service/impl/TTestServiceImplTest.java
+++ b/ruoyi-admin/src/test/java/com/ruoyi/system/service/impl/TTestServiceImplTest.java
@@ -4,7 +4,7 @@
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyLong;
-import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.isNull;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
@@ -12,6 +12,7 @@
import java.math.BigDecimal;
import java.util.Collections;
+import java.util.LinkedHashMap;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
@@ -20,11 +21,12 @@
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.system.domain.TTest;
import com.ruoyi.system.domain.TTestBattery;
-import com.ruoyi.system.domain.TTestBatteryField;
+import com.ruoyi.system.domain.TTestChannelBinding;
+import com.ruoyi.system.domain.TTestPlanStep;
import com.ruoyi.system.domain.TTestWarningThreshold;
import com.ruoyi.system.mapper.TTestMapper;
-/** 测试管理 Service 核心业务单元测试。 */
+/** 测试配置服务的业务契约测试。 */
@ExtendWith(MockitoExtension.class)
class TTestServiceImplTest
{
@@ -35,10 +37,10 @@
private TTestServiceImpl testService;
@Test
- void insertShouldBackfillRelationIdBeforeSavingFields()
+ void createShouldReturnIdentifierAndInitializeIndependentStatuses()
{
- TTest test = validTest(null, "0");
- mockEnabledResources();
+ TTest test = validTest();
+ mockEnabledOptions();
when(testMapper.insertTest(any(TTest.class))).thenAnswer(invocation -> {
invocation.<TTest>getArgument(0).setTestId(10L);
return 1;
@@ -48,118 +50,217 @@
return 1;
}).when(testMapper).insertTestBattery(any(TTestBattery.class));
- assertEquals(1, testService.insertTest(test));
-
- verify(testMapper).insertTestBatteryField(any(TTestBatteryField.class));
- assertEquals(20L, test.getBatteries().get(0).getFields().get(0).getRelationId());
+ assertEquals(10L, testService.createTest(test));
+ assertEquals("WAITING", test.getTestStatus());
+ assertEquals("NOT_MONITORED", test.getMonitoringStatus());
+ assertEquals(7L, test.getCreatorId());
+ verify(testMapper).insertTestPlanStep(any(TTestPlanStep.class));
+ verify(testMapper).insertTestChannelBinding(any(TTestChannelBinding.class));
+ verify(testMapper).insertTestThreshold(any(TTestWarningThreshold.class));
+ verify(testMapper).insertTestAudit(anyLong(), any(), anyLong(), any(), isNull(), any());
}
@Test
- void insertShouldRejectOccupiedBattery()
+ void createShouldAllowMissingCollector()
{
- TTest test = validTest(null, "0");
- mockEnabledResources();
- when(testMapper.countTestingByBatteryNo("BAT-001", null)).thenReturn(1);
+ TTest test = validTest();
+ test.getBatteries().get(0).setCollectorId(null);
+ mockEnabledPeopleAndType();
+ when(testMapper.countBatteryInEnabledGroup(1L, "BAT-001")).thenReturn(1);
+ when(testMapper.countRegisteredChannel(100L)).thenReturn(1);
+ when(testMapper.insertTest(any(TTest.class))).thenAnswer(invocation -> {
+ invocation.<TTest>getArgument(0).setTestId(10L);
+ return 1;
+ });
+ doAnswer(invocation -> {
+ invocation.<TTestBattery>getArgument(0).setRelationId(20L);
+ return 1;
+ }).when(testMapper).insertTestBattery(any(TTestBattery.class));
- ServiceException exception = assertThrows(ServiceException.class, () -> testService.insertTest(test));
+ assertEquals(10L, testService.createTest(test));
- assertEquals("电池号或检测柜测试通道已被检测中的任务占用", exception.getMessage());
+ verify(testMapper, never()).countCollectorEnabled(anyLong());
+ }
+
+ @Test
+ void createShouldRejectBatteryOutsideSelectedGroup()
+ {
+ TTest test = validTest();
+ mockEnabledPeopleAndType();
+ when(testMapper.countBatteryInEnabledGroup(1L, "BAT-001")).thenReturn(0);
+
+ ServiceException exception = assertThrows(ServiceException.class, () -> testService.createTest(test));
+
+ assertEquals("电池号不属于所选启用电池组", exception.getMessage());
verify(testMapper, never()).insertTest(any(TTest.class));
}
@Test
- void updateShouldRejectNonWaitingStatus()
+ void createShouldRejectDisabledCreator()
{
- TTest request = validTest(10L, "0");
- TTest current = validTest(10L, "1");
- when(testMapper.countUserEnabled(1L)).thenReturn(1);
- when(testMapper.countTestTypeEnabled(1L)).thenReturn(1);
- when(testMapper.selectTestById(10L)).thenReturn(current);
- when(testMapper.selectTestBatteries(10L)).thenReturn(current.getBatteries());
- when(testMapper.selectTestBatteryFields(10L)).thenReturn(current.getBatteries().get(0).getFields());
- when(testMapper.selectTestThresholds(10L)).thenReturn(current.getThresholds());
+ TTest test = validTest();
+ when(testMapper.countUserEnabled(7L)).thenReturn(0);
+
+ ServiceException exception = assertThrows(ServiceException.class, () -> testService.createTest(test));
+
+ assertEquals("创建人不存在或已停用", exception.getMessage());
+ verify(testMapper, never()).insertTest(any(TTest.class));
+ }
+
+ @Test
+ void createShouldRejectDisabledPrincipal()
+ {
+ TTest test = validTest();
+ when(testMapper.countUserEnabled(7L)).thenReturn(1);
+ when(testMapper.countUserEnabled(9L)).thenReturn(0);
+
+ ServiceException exception = assertThrows(ServiceException.class, () -> testService.createTest(test));
+
+ assertEquals("测试负责人不存在或已停用", exception.getMessage());
+ verify(testMapper, never()).insertTest(any(TTest.class));
+ }
+
+ @Test
+ void createShouldRejectDuplicatePrimaryChannelBinding()
+ {
+ TTest test = validTest();
+ TTestBattery duplicate = validBattery("BAT-002", 2L, 100L);
+ test.setBatteries(java.util.List.of(test.getBatteries().get(0), duplicate));
+ mockEnabledPeopleAndType();
+ when(testMapper.countBatteryInEnabledGroup(1L, "BAT-001")).thenReturn(1);
+ when(testMapper.countBatteryInEnabledGroup(1L, "BAT-002")).thenReturn(1);
+ when(testMapper.countRegisteredChannel(100L)).thenReturn(1);
+ when(testMapper.countCollectorEnabled(8L)).thenReturn(1);
+
+ ServiceException exception = assertThrows(ServiceException.class, () -> testService.createTest(test));
+
+ assertEquals("同一检测柜通道不可重复绑定", exception.getMessage());
+ verify(testMapper, never()).insertTest(any(TTest.class));
+ }
+
+ @Test
+ void createShouldRejectBatteriesFromDifferentGroups()
+ {
+ TTest test = validTest();
+ TTestBattery otherGroup = validBattery("BAT-002", 2L, 101L);
+ otherGroup.setGroupId(2L);
+ test.setBatteries(java.util.List.of(test.getBatteries().get(0), otherGroup));
+ mockEnabledPeopleAndType();
+ when(testMapper.countBatteryInEnabledGroup(1L, "BAT-001")).thenReturn(1);
+ when(testMapper.countRegisteredChannel(100L)).thenReturn(1);
+ when(testMapper.countCollectorEnabled(8L)).thenReturn(1);
+
+ ServiceException exception = assertThrows(ServiceException.class, () -> testService.createTest(test));
+
+ assertEquals("同一测试只能选择一个电池组", exception.getMessage());
+ verify(testMapper, never()).insertTest(any(TTest.class));
+ }
+
+ @Test
+ void updateShouldRejectConfigurationAfterMonitoringStarted()
+ {
+ TTest request = validTest();
+ request.setTestId(10L);
+ TTest current = validTest();
+ current.setTestId(10L);
+ current.setMonitoringStatus("MONITORING");
+ when(testMapper.selectTestByIdForUpdate(10L)).thenReturn(current);
ServiceException exception = assertThrows(ServiceException.class, () -> testService.updateTest(request));
- assertEquals("仅待检测状态允许编辑草稿", exception.getMessage());
+ assertEquals("开始监测后不能修改测试配置", exception.getMessage());
verify(testMapper, never()).updateTest(any(TTest.class));
}
@Test
- void startShouldTransitionWaitingToTesting()
+ void updateShouldReplaceConfigurationBeforeMonitoringAndAppendAudit()
{
- TTest current = validTest(10L, "0");
- when(testMapper.selectTestById(10L)).thenReturn(current);
- when(testMapper.selectTestBatteries(10L)).thenReturn(current.getBatteries());
- when(testMapper.selectTestBatteryFields(10L)).thenReturn(current.getBatteries().get(0).getFields());
- when(testMapper.selectTestThresholds(10L)).thenReturn(current.getThresholds());
+ TTest request = validTest();
+ request.setTestId(10L);
+ request.setMonitorTimeoutMinutes(45);
+ TTest current = validTest();
+ current.setTestId(10L);
+ current.setCreatorId(7L);
+ current.setMonitoringStatus("NOT_MONITORED");
+ current.setMonitorTimeoutMinutes(30);
+ when(testMapper.selectTestByIdForUpdate(10L)).thenReturn(current);
+ mockEnabledOptions();
+ when(testMapper.updateTest(request)).thenReturn(1);
+ doAnswer(invocation -> {
+ invocation.<TTestBattery>getArgument(0).setRelationId(21L);
+ return 1;
+ }).when(testMapper).insertTestBattery(any(TTestBattery.class));
+
+ assertEquals(1, testService.updateTest(request));
+ assertEquals(45, request.getMonitorTimeoutMinutes());
+ verify(testMapper).deleteTestBindingsByTestId(10L);
+ verify(testMapper).deleteTestPlanStepsByTestId(10L);
+ verify(testMapper).insertTestAudit(anyLong(), any(), anyLong(), any(), any(), any());
+ }
+
+ private void mockEnabledOptions()
+ {
+ mockEnabledPeopleAndType();
when(testMapper.countBatteryInEnabledGroup(1L, "BAT-001")).thenReturn(1);
- when(testMapper.countCabinetEnabled(1L)).thenReturn(1);
- when(testMapper.countCollectorEnabled(1L, 1L)).thenReturn(1);
- when(testMapper.updateTestStatus(10L, "1", "admin")).thenReturn(1);
-
- assertEquals(1, testService.startTest(10L, "admin"));
- verify(testMapper).updateTestStatus(10L, "1", "admin");
+ when(testMapper.countRegisteredChannel(100L)).thenReturn(1);
+ when(testMapper.countCollectorEnabled(8L)).thenReturn(1);
}
- @Test
- void deleteShouldRejectTestingTask()
+ private void mockEnabledPeopleAndType()
{
- TTest current = validTest(10L, "1");
- when(testMapper.selectTestById(10L)).thenReturn(current);
- when(testMapper.selectTestBatteries(10L)).thenReturn(current.getBatteries());
- when(testMapper.selectTestBatteryFields(10L)).thenReturn(current.getBatteries().get(0).getFields());
- when(testMapper.selectTestThresholds(10L)).thenReturn(current.getThresholds());
-
- ServiceException exception = assertThrows(ServiceException.class,
- () -> testService.deleteTestByIds(new Long[] {10L}, "admin"));
-
- assertEquals("检测中或异常测试不能删除", exception.getMessage());
- verify(testMapper, never()).deleteTestById(anyLong(), anyString());
+ when(testMapper.countUserEnabled(7L)).thenReturn(1);
+ when(testMapper.countUserEnabled(9L)).thenReturn(1);
+ when(testMapper.countTestTypeEnabled(3L)).thenReturn(1);
}
- private void mockEnabledResources()
+ private TTest validTest()
{
- when(testMapper.countUserEnabled(1L)).thenReturn(1);
- when(testMapper.countTestTypeEnabled(1L)).thenReturn(1);
- when(testMapper.countBatteryInEnabledGroup(1L, "BAT-001")).thenReturn(1);
- when(testMapper.countCabinetEnabled(1L)).thenReturn(1);
- when(testMapper.countCollectorEnabled(1L, 1L)).thenReturn(1);
- }
-
- private TTest validTest(Long testId, String status)
- {
- TTestBatteryField field = new TTestBatteryField();
- field.setRelationId(20L);
- field.setFieldName("容量");
- field.setFieldValue("100");
-
- TTestBattery battery = new TTestBattery();
- battery.setRelationId(20L);
- battery.setGroupId(1L);
- battery.setBatteryNo("BAT-001");
- battery.setCabinetId(1L);
- battery.setTestChannelNo(0);
- battery.setCollectorId(1L);
- battery.setTemperatureChannelNo(1);
- battery.setPositiveChannelNo(2);
- battery.setNegativeChannelNo(3);
- battery.setFields(Collections.singletonList(field));
+ TTestPlanStep step = new TTestPlanStep();
+ step.setCycleNo(1);
+ step.setStepNo(1);
+ step.setStepType("CONSTANT_CURRENT_CHARGE");
+ step.setStepName("恒流充电");
+ step.setSortOrder(1);
+ LinkedHashMap<String, Object> parameters = new LinkedHashMap<>();
+ parameters.put("currentA", new BigDecimal("1.5"));
+ step.setParameters(parameters);
TTestWarningThreshold threshold = new TTestWarningThreshold();
- threshold.setThresholdType("VOLTAGE:2");
- threshold.setMinValue(BigDecimal.ZERO);
- threshold.setMaxValue(BigDecimal.TEN);
+ threshold.setMetricCode("VOLTAGE");
+ threshold.setMinValue(new BigDecimal("2.5"));
+ threshold.setMaxValue(new BigDecimal("4.2"));
+ threshold.setUnit("V");
+ threshold.setSeverity("WARNING");
TTest test = new TTest();
- test.setTestId(testId);
- test.setTestName("测试任务");
- test.setPrincipalId(1L);
- test.setTestTypeId(1L);
- test.setTestPurpose("验证容量");
- test.setStatus(status);
- test.setBatteries(Collections.singletonList(battery));
+ test.setTestName("低温循环测试");
+ test.setCreatorId(7L);
+ test.setOperatorId(7L);
+ test.setCreateBy("creator");
+ test.setUpdateBy("creator");
+ test.setPrincipalId(9L);
+ test.setTestTypeId(3L);
+ test.setTestPurpose("验证低温循环性能");
+ test.setMonitorTimeoutMinutes(30);
+ test.setBatteries(Collections.singletonList(validBattery("BAT-001", 1L, 100L)));
+ test.setPlanSteps(Collections.singletonList(step));
test.setThresholds(Collections.singletonList(threshold));
return test;
}
+
+ private TTestBattery validBattery(String batteryNo, Long relationId, Long channelId)
+ {
+ TTestChannelBinding binding = new TTestChannelBinding();
+ binding.setChannelId(channelId);
+ binding.setExpectedBarcode("CODE-" + batteryNo);
+
+ TTestBattery battery = new TTestBattery();
+ battery.setRelationId(relationId);
+ battery.setGroupId(1L);
+ battery.setBatteryNo(batteryNo);
+ battery.setCollectorId(8L);
+ battery.setBinding(binding);
+ battery.setFields(Collections.emptyList());
+ return battery;
+ }
}
--
Gitblit v1.7.1