yeg
2026-09-29 b78295e8da96c3e5e76befeef9582ce5273dbb74
ruoyi-admin/src/test/java/com/battery/business/service/impl/TestWarningExceptionServiceTest.java
@@ -3,18 +3,44 @@
import static org.mockito.ArgumentMatchers.*;
import static org.mockito.Mockito.*;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import org.junit.jupiter.api.Test;
import com.ruoyi.common.exception.ServiceException;
import com.battery.business.domain.TTest;
import com.battery.business.domain.TTestWarningException;
import com.battery.business.domain.TTestWarningThreshold;
import com.battery.business.mapper.TTestMapper;
/** 测试预警仅由成功接收测量值触发,并通过持久层原子聚合。 */
/** 阈值异常与接收中的离线异常分别判定,并通过持久层原子聚合。 */
class TestWarningExceptionServiceTest {
    @Test
    void recordsOfflineSourcesOnlyWhileReceivingWithoutInventingMeasurements() {
        TTestMapper mapper = mock(TTestMapper.class);
        var service = new TestWarningExceptionService(mapper);
        TTest test = new TTest();
        test.setTestId(1L);
        test.setTestStatus("RUNNING");
        test.setReceptionStatus("RECEIVING");
        Date now = new Date();
        when(mapper.selectOfflineTestSources(1L)).thenReturn(List.of(
                new com.battery.business.domain.vo.OfflineTestSource("CABINET_CHANNEL", "sim:22:1:1:1"),
                new com.battery.business.domain.vo.OfflineTestSource("COLLECTOR", "9")));
        service.recordOfflineSources(test, now);
        verify(mapper).upsertOfflineException(1L, "CABINET_CHANNEL", "sim:22:1:1:1", now);
        verify(mapper).upsertOfflineException(1L, "COLLECTOR", "9", now);
        clearInvocations(mapper);
        for (String state : List.of("PAUSED", "ENDED", "NOT_STARTED")) {
            test.setReceptionStatus(state);
            service.recordOfflineSources(test, now);
        }
        verifyNoInteractions(mapper);
    }
    @Test
    void evaluatesOnlyOutOfRangeValues() {
        TTestMapper mapper = mock(TTestMapper.class);
@@ -23,24 +49,45 @@
        service.evaluate(test, "COLLECTOR", "adapter:9:S-01", "temperature", new BigDecimal("31"), "℃", new Date());
        service.evaluate(test, "COLLECTOR", "adapter:9:S-01", "temperature", new BigDecimal("20"), "℃", new Date());
        service.evaluate(test, "COLLECTOR", "adapter:9:S-01", "temperature", new BigDecimal("0"), "℃", new Date());
        service.evaluate(test, "COLLECTOR", "adapter:9:S-01", "temperature", new BigDecimal("30"), "℃", new Date());
        service.evaluate(test, "COLLECTOR", "adapter:9:S-01", "temperature", null, "℃", new Date());
        verify(mapper, times(1)).upsertWarningException(eq(1L), eq(11L), eq("COLLECTOR"), eq("adapter:9:S-01"),
                eq("temperature"), eq(new BigDecimal("31")), eq("℃"), anyString(), eq("WARNING"), any(Date.class));
    }
    @Test
    void closesOpenExceptionAndAppendsAuditInServiceOperation() {
    void nonReceivingTestsDoNotCreateThresholdTodos() {
        var mapper = mock(TTestMapper.class);
        var service = new TestWarningExceptionService(mapper);
        var test = testWithThreshold("TEMPERATURE", new BigDecimal("8"), new BigDecimal("33"));
        for (String reception : List.of("PAUSED", "ENDED", "NOT_STARTED")) {
            test.setReceptionStatus(reception);
            service.evaluate(test, "COLLECTOR", "9:S-01", "temperature", new BigDecimal("38"), "℃", new Date());
        }
        verifyNoInteractions(mapper);
    }
    @Test
    void closesOpenExceptionOnlyForTestPrincipalWithHandlingNote() {
        TTestMapper mapper = mock(TTestMapper.class);
        TestWarningExceptionService service = new TestWarningExceptionService(mapper);
        TTestWarningException exception = new TTestWarningException();
        exception.setExceptionId(7L);
        exception.setTestId(1L);
        TTest test = new TTest();
        test.setTestId(1L);
        test.setPrincipalId(22L);
        when(mapper.selectWarningExceptionById(7L)).thenReturn(exception);
        when(mapper.selectTestById(1L)).thenReturn(test);
        when(mapper.closeWarningException(eq(7L), eq(22L), eq("负责人"), any(Date.class), eq("已核实"))).thenReturn(1);
        int rows = service.close(7L, 22L, "负责人", "已核实");
        assertEquals(exception, service.closeByPrincipal(7L, 22L, "负责人", "已核实"));
        assertEquals(1, rows);
        // 归属校验与处理结果必填都由服务层负责,Controller 不再判断业务规则。
        assertThrows(ServiceException.class, () -> service.closeByPrincipal(7L, 23L, "其他人", "已核实"));
        assertThrows(ServiceException.class, () -> service.closeByPrincipal(7L, 22L, "负责人", " "));
    }
    private static TTest testWithThreshold(String metric, BigDecimal min, BigDecimal max) {
@@ -54,6 +101,8 @@
        TTest test = new TTest();
        test.setTestId(1L);
        test.setThresholds(List.of(threshold));
        test.setTestStatus("RUNNING");
        test.setReceptionStatus("RECEIVING");
        return test;
    }
}