puzhibing
2026-08-17 df76ce9a356dfee029a63de4aae58c34dc9b7329
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
package com.ruoyi.system.service.impl;
 
import java.math.BigDecimal;
 
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
 
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.ArgumentCaptor;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.system.domain.TDetectionCabinet;
import com.ruoyi.system.mapper.TDetectionCabinetMapper;
 
/**
 * 检测柜业务层单元测试,验证字段规范化、状态限制及唯一性校验等关键规则。
 */
@ExtendWith(MockitoExtension.class)
class TDetectionCabinetServiceImplTest
{
    @Mock
    private TDetectionCabinetMapper detectionCabinetMapper;
 
    @InjectMocks
    private TDetectionCabinetServiceImpl detectionCabinetService;
 
    private TDetectionCabinet detectionCabinet;
 
    /**
     * 初始化一条满足新增校验的检测柜 Mock 数据。
     */
    @BeforeEach
    void setUp()
    {
        detectionCabinet = new TDetectionCabinet();
        detectionCabinet.setCabinetCode(" CABINET-001 ");
        detectionCabinet.setCabinetName(" 一号检测柜 ");
        detectionCabinet.setIpAddress(" 192.168.1.10 ");
        detectionCabinet.setMacAddress("aa-bb-cc-dd-ee-ff");
        detectionCabinet.setManufacturer(" 厂商 ");
        detectionCabinet.setModel(" 型号A ");
        detectionCabinet.setCapacity(new BigDecimal("120.50"));
        detectionCabinet.setChannelCount(8);
        detectionCabinet.setRemark(" 备注 ");
    }
 
    /**
     * 验证新增时会规范化基础字段并初始化运行状态。
     */
    @Test
    void insertDetectionCabinetShouldNormalizeFieldsAndInitializeStatus()
    {
        when(detectionCabinetMapper.selectByCabinetCode("CABINET-001")).thenReturn(null);
        when(detectionCabinetMapper.selectByMacAddress("AA:BB:CC:DD:EE:FF")).thenReturn(null);
        when(detectionCabinetMapper.insertDetectionCabinet(any(TDetectionCabinet.class))).thenReturn(1);
 
        int rows = detectionCabinetService.insertDetectionCabinet(detectionCabinet);
 
        ArgumentCaptor<TDetectionCabinet> captor = ArgumentCaptor.forClass(TDetectionCabinet.class);
        verify(detectionCabinetMapper).insertDetectionCabinet(captor.capture());
        TDetectionCabinet savedCabinet = captor.getValue();
        assertEquals(1, rows);
        assertEquals("CABINET-001", savedCabinet.getCabinetCode());
        assertEquals("一号检测柜", savedCabinet.getCabinetName());
        assertEquals("192.168.1.10", savedCabinet.getIpAddress());
        assertEquals("AA:BB:CC:DD:EE:FF", savedCabinet.getMacAddress());
        assertEquals(new BigDecimal("120.50"), savedCabinet.getCapacity());
        assertEquals("0", savedCabinet.getOnlineStatus());
        assertEquals("0", savedCabinet.getTestStatus());
        assertEquals("0", savedCabinet.getStatus());
        assertEquals("0", savedCabinet.getDelFlag());
        assertNull(savedCabinet.getCurrentTest());
    }
 
    /**
     * 验证重复设备编码会阻止新增且不会执行写库操作。
     */
    @Test
    void insertDetectionCabinetShouldRejectDuplicateCabinetCode()
    {
        TDetectionCabinet existing = new TDetectionCabinet();
        existing.setCabinetId(2L);
        when(detectionCabinetMapper.selectByCabinetCode("CABINET-001")).thenReturn(existing);
 
        ServiceException exception = assertThrows(ServiceException.class,
                () -> detectionCabinetService.insertDetectionCabinet(detectionCabinet));
 
        assertEquals("设备编码已存在", exception.getMessage());
        verify(detectionCabinetMapper, never()).insertDetectionCabinet(any(TDetectionCabinet.class));
    }
 
    /**
     * 验证非法 IP 地址会阻止新增。
     */
    @Test
    void insertDetectionCabinetShouldRejectInvalidIpAddress()
    {
        detectionCabinet.setIpAddress("invalid-ip");
 
        ServiceException exception = assertThrows(ServiceException.class,
                () -> detectionCabinetService.insertDetectionCabinet(detectionCabinet));
 
        assertEquals("IP地址格式不正确", exception.getMessage());
        verify(detectionCabinetMapper, never()).insertDetectionCabinet(any(TDetectionCabinet.class));
    }
 
    /**
     * 验证测试中的检测柜不能被禁用。
     */
    @Test
    void updateDetectionCabinetStatusShouldRejectDisablingTestingCabinet()
    {
        TDetectionCabinet current = new TDetectionCabinet();
        current.setCabinetId(1L);
        current.setStatus("0");
        current.setTestStatus("1");
        when(detectionCabinetMapper.selectDetectionCabinetById(1L)).thenReturn(current);
 
        TDetectionCabinet statusCommand = new TDetectionCabinet();
        statusCommand.setCabinetId(1L);
        statusCommand.setStatus("1");
 
        ServiceException exception = assertThrows(ServiceException.class,
                () -> detectionCabinetService.updateDetectionCabinetStatus(statusCommand));
 
        assertEquals("检测柜正在测试,不能禁用", exception.getMessage());
        verify(detectionCabinetMapper, never()).updateDetectionCabinetStatus(any(TDetectionCabinet.class));
    }
 
    /**
     * 验证检测中的检测柜允许执行启用操作。
     */
    @Test
    void updateDetectionCabinetStatusShouldAllowEnablingTestingCabinet()
    {
        TDetectionCabinet current = new TDetectionCabinet();
        current.setCabinetId(1L);
        current.setStatus("1");
        current.setTestStatus("1");
        when(detectionCabinetMapper.selectDetectionCabinetById(1L)).thenReturn(current);
        when(detectionCabinetMapper.updateDetectionCabinetStatus(any(TDetectionCabinet.class))).thenReturn(1);
 
        TDetectionCabinet statusCommand = new TDetectionCabinet();
        statusCommand.setCabinetId(1L);
        statusCommand.setStatus("0");
 
        int rows = detectionCabinetService.updateDetectionCabinetStatus(statusCommand);
 
        assertEquals(1, rows);
        verify(detectionCabinetMapper).updateDetectionCabinetStatus(statusCommand);
    }
 
    /**
     * 验证重复提交相同状态时按幂等成功处理,不重复写库。
     */
    @Test
    void updateDetectionCabinetStatusShouldBeIdempotent()
    {
        TDetectionCabinet current = new TDetectionCabinet();
        current.setCabinetId(1L);
        current.setStatus("0");
        current.setTestStatus("0");
        when(detectionCabinetMapper.selectDetectionCabinetById(1L)).thenReturn(current);
 
        TDetectionCabinet statusCommand = new TDetectionCabinet();
        statusCommand.setCabinetId(1L);
        statusCommand.setStatus("0");
 
        int rows = detectionCabinetService.updateDetectionCabinetStatus(statusCommand);
 
        assertEquals(1, rows);
        verify(detectionCabinetMapper, never()).updateDetectionCabinetStatus(any(TDetectionCabinet.class));
    }
 
    /**
     * 验证批量删除会先检查所有检测柜,存在测试中记录时不删除任何数据。
     */
    @Test
    void deleteDetectionCabinetByIdsShouldRejectTestingCabinetBeforeDeleting()
    {
        TDetectionCabinet normal = new TDetectionCabinet();
        normal.setCabinetId(1L);
        normal.setTestStatus("0");
        TDetectionCabinet testing = new TDetectionCabinet();
        testing.setCabinetId(2L);
        testing.setTestStatus("1");
        when(detectionCabinetMapper.selectDetectionCabinetById(1L)).thenReturn(normal);
        when(detectionCabinetMapper.selectDetectionCabinetById(2L)).thenReturn(testing);
 
        ServiceException exception = assertThrows(ServiceException.class,
                () -> detectionCabinetService.deleteDetectionCabinetByIds(new Long[] { 1L, 2L }, "admin"));
 
        assertEquals("检测柜正在测试,不能删除", exception.getMessage());
        verify(detectionCabinetMapper, never()).deleteDetectionCabinetById(any(), any());
    }
 
    /**
     * 验证编辑时唯一性查询命中当前记录仍视为唯一。
     */
    @Test
    void checkUniqueShouldAllowCurrentCabinet()
    {
        TDetectionCabinet current = new TDetectionCabinet();
        current.setCabinetId(1L);
        current.setCabinetCode("CABINET-001");
        current.setMacAddress("AA:BB:CC:DD:EE:FF");
        when(detectionCabinetMapper.selectByCabinetCode("CABINET-001")).thenReturn(current);
        when(detectionCabinetMapper.selectByMacAddress("AA:BB:CC:DD:EE:FF")).thenReturn(current);
 
        assertTrue(detectionCabinetService.checkCabinetCodeUnique(current));
        assertTrue(detectionCabinetService.checkMacAddressUnique(current));
    }
}