package com.ruoyi.system.service.impl; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyLong; 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.TBatteryGroupField; import com.ruoyi.system.mapper.TBatteryGroupFieldMapper; /** * 电池组字段 Service 单元测试。 */ @ExtendWith(MockitoExtension.class) class TBatteryGroupFieldServiceImplTest { @Mock private TBatteryGroupFieldMapper batteryGroupFieldMapper; @InjectMocks private TBatteryGroupFieldServiceImpl batteryGroupFieldService; private TBatteryGroupField field; @BeforeEach void setUp() { field = batteryGroupField(1L, "电流", "text", "0"); } @Test void insertShouldNormalizeFieldsAndInitializeStatus() { field.setFieldId(null); field.setFieldName(" 电流 "); field.setFieldType(" text "); field.setRemark(" 备注 "); when(batteryGroupFieldMapper.insertBatteryGroupField(any(TBatteryGroupField.class))).thenReturn(1); int rows = batteryGroupFieldService.insertBatteryGroupField(field); ArgumentCaptor captor = ArgumentCaptor.forClass(TBatteryGroupField.class); verify(batteryGroupFieldMapper).insertBatteryGroupField(captor.capture()); TBatteryGroupField saved = captor.getValue(); assertEquals(1, rows); assertEquals("电流", saved.getFieldName()); assertEquals("text", saved.getFieldType()); assertEquals("备注", saved.getRemark()); assertEquals("0", saved.getStatus()); assertEquals(0L, saved.getDelFlag()); } @Test void insertShouldRejectBlankName() { field.setFieldId(null); field.setFieldName(" "); ServiceException exception = assertThrows(ServiceException.class, () -> batteryGroupFieldService.insertBatteryGroupField(field)); assertEquals("字段名称不能为空", exception.getMessage()); verify(batteryGroupFieldMapper, never()).insertBatteryGroupField(any(TBatteryGroupField.class)); } @Test void insertShouldAcceptExistingFieldTypes() { field.setFieldId(null); field.setFieldType("number"); when(batteryGroupFieldMapper.insertBatteryGroupField(any(TBatteryGroupField.class))).thenReturn(1); assertEquals(1, batteryGroupFieldService.insertBatteryGroupField(field)); verify(batteryGroupFieldMapper).insertBatteryGroupField(field); } @Test void insertShouldRejectUnsupportedFieldType() { field.setFieldId(null); field.setFieldType("boolean"); ServiceException exception = assertThrows(ServiceException.class, () -> batteryGroupFieldService.insertBatteryGroupField(field)); assertEquals("字段类型仅支持text、number、time或remark", exception.getMessage()); verify(batteryGroupFieldMapper, never()).insertBatteryGroupField(any(TBatteryGroupField.class)); } @Test void insertShouldRejectDuplicateName() { field.setFieldId(null); when(batteryGroupFieldMapper.selectBatteryGroupFieldByName("电流")) .thenReturn(batteryGroupField(2L, "电流", "text", "0")); ServiceException exception = assertThrows(ServiceException.class, () -> batteryGroupFieldService.insertBatteryGroupField(field)); assertEquals("字段名称已存在", exception.getMessage()); verify(batteryGroupFieldMapper, never()).insertBatteryGroupField(any(TBatteryGroupField.class)); } @Test void updateShouldAllowCurrentName() { when(batteryGroupFieldMapper.selectBatteryGroupFieldById(1L)).thenReturn(field); when(batteryGroupFieldMapper.selectBatteryGroupFieldByName("电流")).thenReturn(field); when(batteryGroupFieldMapper.updateBatteryGroupField(any(TBatteryGroupField.class))).thenReturn(1); assertEquals(1, batteryGroupFieldService.updateBatteryGroupField(field)); verify(batteryGroupFieldMapper).updateBatteryGroupField(field); } @Test void updateStatusShouldRejectInvalidStatus() { TBatteryGroupField command = statusCommand("2"); ServiceException exception = assertThrows(ServiceException.class, () -> batteryGroupFieldService.updateBatteryGroupFieldStatus(command)); assertEquals("状态只能为0或1", exception.getMessage()); verify(batteryGroupFieldMapper, never()).updateBatteryGroupFieldStatus(any(TBatteryGroupField.class)); } @Test void updateStatusShouldDisableField() { when(batteryGroupFieldMapper.selectBatteryGroupFieldById(1L)).thenReturn(field); when(batteryGroupFieldMapper.updateBatteryGroupFieldStatus(any(TBatteryGroupField.class))).thenReturn(1); TBatteryGroupField command = statusCommand("1"); assertEquals(1, batteryGroupFieldService.updateBatteryGroupFieldStatus(command)); verify(batteryGroupFieldMapper).updateBatteryGroupFieldStatus(command); } @Test void updateStatusShouldBeIdempotent() { when(batteryGroupFieldMapper.selectBatteryGroupFieldById(1L)).thenReturn(field); TBatteryGroupField command = statusCommand("0"); assertEquals(1, batteryGroupFieldService.updateBatteryGroupFieldStatus(command)); verify(batteryGroupFieldMapper, never()).updateBatteryGroupFieldStatus(any(TBatteryGroupField.class)); } @Test void deleteByIdsShouldValidateAllBeforeAnyDelete() { when(batteryGroupFieldMapper.selectBatteryGroupFieldById(1L)).thenReturn(field); when(batteryGroupFieldMapper.selectBatteryGroupFieldById(2L)).thenReturn(null); ServiceException exception = assertThrows(ServiceException.class, () -> batteryGroupFieldService.deleteBatteryGroupFieldByIds(new Long[] { 1L, 2L }, "admin")); assertEquals("电池组字段不存在", exception.getMessage()); verify(batteryGroupFieldMapper, never()).deleteBatteryGroupFieldById(anyLong(), any(String.class)); } @Test void deleteByIdsShouldDeleteAllValidatedFields() { when(batteryGroupFieldMapper.selectBatteryGroupFieldById(1L)).thenReturn(field); when(batteryGroupFieldMapper.selectBatteryGroupFieldById(2L)) .thenReturn(batteryGroupField(2L, "电压", "text", "0")); when(batteryGroupFieldMapper.deleteBatteryGroupFieldById(anyLong(), any(String.class))).thenReturn(1); assertEquals(2, batteryGroupFieldService.deleteBatteryGroupFieldByIds(new Long[] { 1L, 2L }, "admin")); verify(batteryGroupFieldMapper).deleteBatteryGroupFieldById(1L, "admin"); verify(batteryGroupFieldMapper).deleteBatteryGroupFieldById(2L, "admin"); } @Test void deleteByIdsShouldRejectReferencedField() { when(batteryGroupFieldMapper.selectBatteryGroupFieldById(1L)).thenReturn(field); when(batteryGroupFieldMapper.countFieldReferences(1L)).thenReturn(1); ServiceException exception = assertThrows(ServiceException.class, () -> batteryGroupFieldService.deleteBatteryGroupFieldByIds(new Long[] { 1L }, "admin")); assertEquals("字段已被模板或电池组引用,不能删除", exception.getMessage()); verify(batteryGroupFieldMapper, never()).deleteBatteryGroupFieldById(anyLong(), any(String.class)); } private TBatteryGroupField statusCommand(String status) { TBatteryGroupField command = new TBatteryGroupField(); command.setFieldId(1L); command.setStatus(status); command.setUpdateBy("admin"); return command; } private TBatteryGroupField batteryGroupField(Long id, String name, String type, String status) { TBatteryGroupField value = new TBatteryGroupField(); value.setFieldId(id); value.setFieldName(name); value.setFieldType(type); value.setStatus(status); return value; } }