package cn.iocoder.yudao.module.mes.service.safety;
|
|
import cn.iocoder.yudao.module.hrm.api.employee.HrmEmployeeApi;
|
import cn.iocoder.yudao.module.hrm.api.employee.dto.HrmEmployeeSimpleDTO;
|
import cn.iocoder.yudao.module.mes.dal.dataobject.md.workstation.MesMdWorkshopDO;
|
|
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.extension.ExtendWith;
|
import org.mockito.InjectMocks;
|
import org.mockito.Mock;
|
import org.mockito.junit.jupiter.MockitoExtension;
|
import org.mockito.junit.jupiter.MockitoSettings;
|
import org.mockito.quality.Strictness;
|
|
import java.util.List;
|
import java.util.Map;
|
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertNull;
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
|
/**
|
* {@link SafetyRefResolver} 空集合场景回归测试
|
*
|
* <p>背景:{@code Map.of()} 是空且不可变的 Map,它的 {@code get(null)} 会抛 NPE,
|
* 而 {@code Map.of().get(非null)} 不会。安全生产模块里「组织 / 证件 / 隐患」等
|
* 记录在未关联员工(leaderId、employeeId 为 null)时,就会走到 {@code map.get(null)},
|
* 从而在列表页直接 500。</p>
|
*
|
* <p>这里锁死约定:空集合必须返回可接受 null key 的空 Map。</p>
|
*/
|
@ExtendWith(MockitoExtension.class)
|
@MockitoSettings(strictness = Strictness.LENIENT)
|
class SafetyRefResolverEmptyCollectionTest {
|
|
@InjectMocks
|
private SafetyRefResolver resolver;
|
|
@Mock
|
private HrmEmployeeApi hrmEmployeeApi;
|
@Mock
|
private cn.iocoder.yudao.module.mes.dal.mysql.md.workstation.MesMdWorkshopMapper workshopMapper;
|
|
/** 空集合:必须能 get(null) 而不抛 NPE(这就是线上 NPE 的根因) */
|
@Test
|
void employeeMap_emptyCollection_getNullShouldNotThrow() {
|
Map<Long, HrmEmployeeSimpleDTO> map = resolver.employeeMap(List.of());
|
assertTrue(map.isEmpty());
|
// Map.of() 在这里会抛 NullPointerException
|
assertNull(map.get(null), "空集合返回的 Map 必须允许用 null 作为 key 查询");
|
}
|
|
/** 集合里全是 null:过滤后为空,同样必须能 get(null) */
|
@Test
|
void employeeMap_allNullElements_getNullShouldNotThrow() {
|
Map<Long, HrmEmployeeSimpleDTO> map = resolver.employeeMap(java.util.Arrays.asList((Long) null, null));
|
assertTrue(map.isEmpty());
|
assertNull(map.get(null));
|
}
|
|
/** null 集合本身 */
|
@Test
|
void employeeMap_nullCollection_getNullShouldNotThrow() {
|
Map<Long, HrmEmployeeSimpleDTO> map = resolver.employeeMap(null);
|
assertTrue(map.isEmpty());
|
assertNull(map.get(null));
|
}
|
|
@Test
|
void workshopMap_emptyCollection_getNullShouldNotThrow() {
|
Map<Long, MesMdWorkshopDO> map = resolver.workshopMap(List.of());
|
assertTrue(map.isEmpty());
|
assertNull(map.get(null), "空集合返回的 Map 必须允许用 null 作为 key 查询");
|
}
|
|
@Test
|
void workshopMap_allNullElements_getNullShouldNotThrow() {
|
Map<Long, MesMdWorkshopDO> map = resolver.workshopMap(java.util.Arrays.asList((Long) null));
|
assertTrue(map.isEmpty());
|
assertNull(map.get(null));
|
}
|
|
@Test
|
void workshopMap_nullCollection_getNullShouldNotThrow() {
|
Map<Long, MesMdWorkshopDO> map = resolver.workshopMap(null);
|
assertTrue(map.isEmpty());
|
assertNull(map.get(null));
|
}
|
|
/** 返回的 Map 应该是可变的(避免后续 put 抛 UnsupportedOperationException) */
|
@Test
|
void employeeMap_emptyResultShouldBeMutable() {
|
Map<Long, HrmEmployeeSimpleDTO> map = resolver.employeeMap(List.of());
|
map.put(1L, new HrmEmployeeSimpleDTO());
|
assertEquals(1, map.size());
|
}
|
|
@Test
|
void workshopMap_emptyResultShouldBeMutable() {
|
Map<Long, MesMdWorkshopDO> map = resolver.workshopMap(List.of());
|
map.put(1L, new MesMdWorkshopDO());
|
assertEquals(1, map.size());
|
}
|
|
}
|