字典类型service/controller单元测试完善

This commit is contained in:
gaoqr
2026-01-14 17:38:07 +08:00
parent 1e052edbe7
commit 76a1ad2003
3 changed files with 409 additions and 191 deletions
@@ -1,8 +1,7 @@
package com.cf.imes.module.system.service.dict;
import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.cf.imes.framework.common.enums.DeletedCodeEnum;
import com.cf.imes.framework.common.exception.ServiceException;
import com.cf.imes.framework.common.pojo.PageResult;
@@ -86,8 +85,12 @@ public class DictTypeServiceImpl implements DictTypeService {
// 字典类型发生改变,更新关联字典数据
String oldDictTypeDOType = oldDictTypeDO.getType();
if (ObjectUtil.isAllNotEmpty(oldDictTypeDOType, updateReqVOType) && ObjectUtil.notEqual(oldDictTypeDOType, updateReqVOType)) {
dictDataMapper.update(new LambdaUpdateWrapper<DictDataDO>().set(DictDataDO::getDictType, updateReqVOType).eq(DictDataDO::getDictType, oldDictTypeDOType).eq(DictDataDO::getStatus, DeletedCodeEnum.NOT_DELETED.getStatus()));
if (ObjectUtil.notEqual(oldDictTypeDOType, updateReqVOType)) {
UpdateWrapper<DictDataDO> wrapper = new UpdateWrapper<>();
wrapper.set("dict_type", updateReqVOType);
wrapper.eq("dict_type", oldDictTypeDOType);
wrapper.eq("status", DeletedCodeEnum.NOT_DELETED.getStatus());
dictDataMapper.update(wrapper);
}
}
@@ -125,9 +128,6 @@ public class DictTypeServiceImpl implements DictTypeService {
@VisibleForTesting
void validateDictTypeUnique(Long id, String type) {
if (CharSequenceUtil.isEmpty(type)) {
return;
}
DictTypeDO dictType = dictTypeMapper.selectByType(type);
if (dictType == null) {
return;
@@ -0,0 +1,192 @@
package com.cf.imes.module.system.controller.admin.dict;
import com.cf.imes.framework.common.enums.CommonStatusEnum;
import com.cf.imes.framework.common.pojo.PageResult;
import com.cf.imes.framework.excel.core.util.ExcelUtils;
import com.cf.imes.module.system.controller.admin.dict.vo.type.DictTypeRespVO;
import com.cf.imes.module.system.controller.admin.dict.vo.type.DictTypeSaveReqVO;
import com.cf.imes.module.system.dal.dataobject.dict.DictTypeDO;
import com.cf.imes.module.system.service.dict.DictTypeService;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.servlet.http.HttpServletResponse;
import org.junit.jupiter.api.Test;
import org.mockito.MockedStatic;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.http.MediaType;
import org.springframework.test.context.bean.override.mockito.MockitoBean;
import org.springframework.test.web.servlet.MockMvc;
import java.util.List;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyList;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.mockStatic;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
/**
*
*
* @author Gqr
* @since 2026/1/14 17:25
*/
@WebMvcTest(controllers = DictTypeController.class, excludeAutoConfiguration = SecurityAutoConfiguration.class)
public class DictTypeControllerTest {
@Autowired
private MockMvc mockMvc;
@MockitoBean
private DictTypeService dictTypeService;
@Autowired
private ObjectMapper objectMapper;
@Test
void testCreateDictType_success() throws Exception {
DictTypeSaveReqVO reqVO = new DictTypeSaveReqVO();
reqVO.setName("测试类型");
reqVO.setType("test_type");
reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus());
when(dictTypeService.createDictType(any())).thenReturn(100L);
mockMvc.perform(post("/system/dict-type/create")
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(reqVO)))
.andExpect(status().isOk())
.andExpect(jsonPath("$.data").value(100));
verify(dictTypeService).createDictType(any());
}
@Test
void testUpdateDictType_success() throws Exception {
DictTypeSaveReqVO reqVO = new DictTypeSaveReqVO();
reqVO.setId(1L);
reqVO.setName("类型B");
reqVO.setType("typeB");
reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus());
doNothing().when(dictTypeService).updateDictType(any());
mockMvc.perform(put("/system/dict-type/update")
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(reqVO)))
.andExpect(status().isOk())
.andExpect(jsonPath("$.data").value(true));
verify(dictTypeService).updateDictType(any());
}
@Test
void testDeleteDictType_success() throws Exception {
doNothing().when(dictTypeService).deleteDictType(1L);
mockMvc.perform(delete("/system/dict-type/delete")
.param("id", "1"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.data").value(true));
verify(dictTypeService).deleteDictType(1L);
}
@Test
void testPageDictTypes_success() throws Exception {
PageResult<DictTypeDO> pageResult = new PageResult<>();
DictTypeDO dictTypeDO = new DictTypeDO();
dictTypeDO.setId(1L);
dictTypeDO.setName("类型C");
dictTypeDO.setType("typeC");
pageResult.setList(List.of(dictTypeDO));
pageResult.setTotal(1L);
when(dictTypeService.getDictTypePage(any())).thenReturn(pageResult);
mockMvc.perform(get("/system/dict-type/page")
.param("pageNo", "1")
.param("pageSize", "10"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.data.list[0].id").value(1))
.andExpect(jsonPath("$.data.list[0].name").value("类型C"))
.andExpect(jsonPath("$.data.list[0].type").value("typeC"));
}
@Test
void testGetDictType_success() throws Exception {
DictTypeDO dictTypeDO = new DictTypeDO();
dictTypeDO.setId(1L);
dictTypeDO.setName("类型D");
dictTypeDO.setType("typeD");
when(dictTypeService.getDictType(1L)).thenReturn(dictTypeDO);
mockMvc.perform(get("/system/dict-type/get")
.param("id", "1"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.data.id").value(1))
.andExpect(jsonPath("$.data.name").value("类型D"))
.andExpect(jsonPath("$.data.type").value("typeD"));
}
@Test
void testGetSimpleDictTypeList_success() throws Exception {
DictTypeDO dictTypeDO = new DictTypeDO();
dictTypeDO.setId(1L);
dictTypeDO.setName("类型E");
dictTypeDO.setType("typeE");
when(dictTypeService.getDictTypeList()).thenReturn(List.of(dictTypeDO));
mockMvc.perform(get("/system/dict-type/list-all-simple"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.data[0].id").value(1))
.andExpect(jsonPath("$.data[0].name").value("类型E"))
.andExpect(jsonPath("$.data[0].type").value("typeE"));
}
@Test
void testExport_success() throws Exception {
// mock Service 返回分页数据
DictTypeDO dictTypeDO = new DictTypeDO();
dictTypeDO.setId(1L);
dictTypeDO.setName("类型A");
dictTypeDO.setType("typeA");
PageResult<DictTypeDO> pageResult = new PageResult<>();
pageResult.setList(List.of(dictTypeDO));
when(dictTypeService.getDictTypePage(any())).thenReturn(pageResult);
// mock ExcelUtils.write 静态方法
try (MockedStatic<ExcelUtils> excelMock = mockStatic(ExcelUtils.class)) {
mockMvc.perform(get("/system/dict-type/export")
.param("pageNo", "1")
.param("pageSize", "10"))
.andExpect(status().isOk());
// 验证 ExcelUtils.write 被调用
excelMock.verify(() -> ExcelUtils.write(
any(HttpServletResponse.class),
eq("字典类型.xls"),
eq("数据"),
eq(DictTypeRespVO.class),
anyList()
));
}
// 验证 Service 被调用
verify(dictTypeService).getDictTypePage(any());
}
}
@@ -1,271 +1,297 @@
package com.cf.imes.module.system.service.dict;
import com.cf.imes.framework.common.enums.CommonStatusEnum;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.cf.imes.framework.common.pojo.PageResult;
import com.cf.imes.framework.common.util.collection.ArrayUtils;
import com.cf.imes.framework.test.core.ut.BaseDbUnitTest;
import com.cf.imes.framework.test.core.ut.BaseMockitoUnitTest;
import com.cf.imes.module.system.controller.admin.dict.vo.type.DictTypePageReqVO;
import com.cf.imes.module.system.controller.admin.dict.vo.type.DictTypeSaveReqVO;
import com.cf.imes.module.system.dal.dataobject.dict.DictTypeDO;
import com.cf.imes.module.system.dal.mysql.dict.DictDataMapper;
import com.cf.imes.module.system.dal.mysql.dict.DictTypeMapper;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.context.annotation.Import;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import jakarta.annotation.Resource;
import java.util.List;
import java.util.function.Consumer;
import static cn.hutool.core.util.RandomUtil.randomEle;
import static com.cf.imes.framework.common.util.date.LocalDateTimeUtils.buildBetweenTime;
import static com.cf.imes.framework.common.util.date.LocalDateTimeUtils.buildTime;
import static com.cf.imes.framework.common.util.object.ObjectUtils.cloneIgnoreId;
import static com.cf.imes.framework.test.core.util.AssertUtils.assertPojoEquals;
import static com.cf.imes.framework.test.core.util.AssertUtils.assertServiceException;
import static com.cf.imes.framework.test.core.util.RandomUtils.*;
import static com.cf.imes.module.system.enums.ErrorCodeConstants.*;
import static com.cf.imes.module.system.enums.ErrorCodeConstants.DICT_TYPE_HAS_CHILDREN;
import static com.cf.imes.module.system.enums.ErrorCodeConstants.DICT_TYPE_NAME_DUPLICATE;
import static com.cf.imes.module.system.enums.ErrorCodeConstants.DICT_TYPE_NOT_EXISTS;
import static com.cf.imes.module.system.enums.ErrorCodeConstants.DICT_TYPE_TYPE_DUPLICATE;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.argThat;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@Import(DictTypeServiceImpl.class)
public class DictTypeServiceImplTest extends BaseDbUnitTest {
public class DictTypeServiceImplTest extends BaseMockitoUnitTest {
@Resource
@InjectMocks
private DictTypeServiceImpl dictTypeService;
@Resource
@Mock
private DictTypeMapper dictTypeMapper;
@MockBean
@Mock
private DictDataMapper dictDataMapper;
@Mock
private DictDataService dictDataService;
@Test
public void testGetDictTypePage() {
// mock 数据
DictTypeDO dbDictType = randomPojo(DictTypeDO.class, o -> { // 等会查询到
o.setName("yunai");
o.setType("晨丰");
o.setStatus(CommonStatusEnum.ENABLE.getStatus());
o.setCreateTime(buildTime(2021, 1, 15));
});
dictTypeMapper.insert(dbDictType);
// 测试 name 不匹配
dictTypeMapper.insert(cloneIgnoreId(dbDictType, o -> o.setName("tudou")));
// 测试 type 不匹配
dictTypeMapper.insert(cloneIgnoreId(dbDictType, o -> o.setType("土豆")));
// 测试 status 不匹配
dictTypeMapper.insert(cloneIgnoreId(dbDictType, o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus())));
// 测试 createTime 不匹配
dictTypeMapper.insert(cloneIgnoreId(dbDictType, o -> o.setCreateTime(buildTime(2021, 1, 1))));
// 准备参数
DictTypePageReqVO reqVO = new DictTypePageReqVO();
reqVO.setName("nai");
reqVO.setType("");
reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus());
reqVO.setCreateTime(buildBetweenTime(2021, 1, 10, 2021, 1, 20));
// 调用
PageResult<DictTypeDO> pageResult = dictTypeService.getDictTypePage(reqVO);
// 断言
assertEquals(1, pageResult.getTotal());
assertEquals(1, pageResult.getList().size());
assertPojoEquals(dbDictType, pageResult.getList().get(0));
}
@Test
public void testGetDictType_id() {
// mock 数据
DictTypeDO dbDictType = randomDictTypeDO();
dictTypeMapper.insert(dbDictType);
void testGetDictTypePage_success() {
// 准备参数
Long id = dbDictType.getId();
DictTypePageReqVO reqVO = new DictTypePageReqVO();
PageResult<DictTypeDO> pageResult = new PageResult<>();
pageResult.setTotal(1L);
// mock mapper
when(dictTypeMapper.selectPage(reqVO)).thenReturn(pageResult);
// 调用
DictTypeDO dictType = dictTypeService.getDictType(id);
PageResult<DictTypeDO> result = dictTypeService.getDictTypePage(reqVO);
// 断言
assertNotNull(dictType);
assertPojoEquals(dbDictType, dictType);
assertSame(pageResult, result);
// 校验调用
verify(dictTypeMapper).selectPage(reqVO);
}
@Test
public void testGetDictType_type() {
// mock 数据
DictTypeDO dbDictType = randomDictTypeDO();
dictTypeMapper.insert(dbDictType);
// 准备参数
String type = dbDictType.getType();
void testGetDictTypeById_success() {
DictTypeDO dictType = new DictTypeDO();
dictType.setId(1L);
// 调用
DictTypeDO dictType = dictTypeService.getDictType(type);
// 断言
assertNotNull(dictType);
assertPojoEquals(dbDictType, dictType);
when(dictTypeMapper.selectById(1L)).thenReturn(dictType);
DictTypeDO result = dictTypeService.getDictType(1L);
assertSame(dictType, result);
verify(dictTypeMapper).selectById(1L);
}
@Test
public void testCreateDictType_success() {
// 准备参数
DictTypeSaveReqVO reqVO = randomPojo(DictTypeSaveReqVO.class,
o -> o.setStatus(randomEle(CommonStatusEnum.values()).getStatus()))
.setId(null); // 避免 id 被赋值
void testGetDictTypeByType_success() {
DictTypeDO dictType = new DictTypeDO();
dictType.setType("system");
// 调用
Long dictTypeId = dictTypeService.createDictType(reqVO);
// 断言
assertNotNull(dictTypeId);
// 校验记录的属性是否正确
DictTypeDO dictType = dictTypeMapper.selectById(dictTypeId);
assertPojoEquals(reqVO, dictType, "id");
when(dictTypeMapper.selectByType("system")).thenReturn(dictType);
DictTypeDO result = dictTypeService.getDictType("system");
assertSame(dictType, result);
verify(dictTypeMapper).selectByType("system");
}
@Test
public void testUpdateDictType_success() {
// mock 数据
DictTypeDO dbDictType = randomDictTypeDO();
dictTypeMapper.insert(dbDictType);// @Sql: 先插入出一条存在的数据
// 准备参数
DictTypeSaveReqVO reqVO = randomPojo(DictTypeSaveReqVO.class, o -> {
o.setId(dbDictType.getId()); // 设置更新的 ID
o.setStatus(randomEle(CommonStatusEnum.values()).getStatus());
});
void testCreateDictType_success() {
DictTypeSaveReqVO reqVO = new DictTypeSaveReqVO();
reqVO.setName("系统配置");
reqVO.setType("system");
// mock 唯一性校验
when(dictTypeMapper.selectByName("系统配置")).thenReturn(null);
when(dictTypeMapper.selectByType("system")).thenReturn(null);
// mock insert:模拟 MyBatis 回写 id
doAnswer(invocation -> {
DictTypeDO arg = invocation.getArgument(0);
arg.setId(1L);
return 1;
}).when(dictTypeMapper).insert(any(DictTypeDO.class));
Long id = dictTypeService.createDictType(reqVO);
assertEquals(1L, id);
verify(dictTypeMapper).insert(any(DictTypeDO.class));
}
@Test
void testUpdateDictType_success_noTypeChange() {
DictTypeSaveReqVO reqVO = new DictTypeSaveReqVO();
reqVO.setId(1L);
reqVO.setName("系统");
reqVO.setType("system");
DictTypeDO old = new DictTypeDO();
old.setId(1L);
old.setType("system");
when(dictTypeMapper.selectById(1L)).thenReturn(old);
when(dictTypeMapper.selectByName("系统")).thenReturn(null);
when(dictTypeMapper.selectByType("system")).thenReturn(old);
when(dictTypeMapper.updateById(any(DictTypeDO.class))).thenReturn(1);
// 调用
dictTypeService.updateDictType(reqVO);
// 校验是否更新正确
DictTypeDO dictType = dictTypeMapper.selectById(reqVO.getId()); // 获取最新的
assertPojoEquals(reqVO, dictType);
verify(dictTypeMapper).updateById(any(DictTypeDO.class));
verify(dictDataMapper, Mockito.never()).update(any());
}
@Test
public void testDeleteDictType_success() {
// mock 数据
DictTypeDO dbDictType = randomDictTypeDO();
dictTypeMapper.insert(dbDictType);// @Sql: 先插入出一条存在的数据
// 准备参数
Long id = dbDictType.getId();
void testUpdateDictType_success_typeChanged() {
DictTypeSaveReqVO reqVO = new DictTypeSaveReqVO();
reqVO.setId(1L);
reqVO.setType("new_type");
DictTypeDO old = new DictTypeDO();
old.setId(1L);
old.setType("old_type");
when(dictTypeMapper.selectById(1L)).thenReturn(old);
when(dictTypeMapper.selectByType("new_type")).thenReturn(null);
when(dictTypeMapper.updateById(any(DictTypeDO.class))).thenReturn(1);
when(dictDataMapper.update(any(UpdateWrapper.class))).thenReturn(1);
dictTypeService.updateDictType(reqVO);
// 校验 dict_data 被批量更新
verify(dictDataMapper).update(
argThat((UpdateWrapper wrapper) ->
wrapper.getSqlSet().contains("dict_type")
)
);
// 调用
dictTypeService.deleteDictType(id);
// 校验数据不存在了
assertNull(dictTypeMapper.selectById(id));
}
@Test
public void testDeleteDictType_hasChildren() {
// mock 数据
DictTypeDO dbDictType = randomDictTypeDO();
dictTypeMapper.insert(dbDictType);// @Sql: 先插入出一条存在的数据
// 准备参数
Long id = dbDictType.getId();
// mock 方法
when(dictDataService.getDictDataCountByDictType(eq(dbDictType.getType()))).thenReturn(1L);
void testDeleteDictType_success() {
DictTypeDO dictType = new DictTypeDO();
dictType.setId(1L);
dictType.setType("system");
// 调用, 并断言异常
assertServiceException(() -> dictTypeService.deleteDictType(id), DICT_TYPE_HAS_CHILDREN);
when(dictTypeMapper.selectById(1L)).thenReturn(dictType);
when(dictDataService.getDictDataCountByDictType("system")).thenReturn(0L);
dictTypeService.deleteDictType(1L);
verify(dictTypeMapper).updateToDelete(eq(1L), any());
}
@Test
public void testGetDictTypeList() {
// 准备参数
DictTypeDO dictTypeDO01 = randomDictTypeDO();
dictTypeMapper.insert(dictTypeDO01);
DictTypeDO dictTypeDO02 = randomDictTypeDO();
dictTypeMapper.insert(dictTypeDO02);
// mock 方法
void testDeleteDictType_hasChildren() {
DictTypeDO dictType = new DictTypeDO();
dictType.setId(1L);
dictType.setType("system");
// 调用
List<DictTypeDO> dictTypeDOList = dictTypeService.getDictTypeList();
// 断言
assertEquals(2, dictTypeDOList.size());
assertPojoEquals(dictTypeDO01, dictTypeDOList.get(0));
assertPojoEquals(dictTypeDO02, dictTypeDOList.get(1));
when(dictTypeMapper.selectById(1L)).thenReturn(dictType);
when(dictDataService.getDictDataCountByDictType("system")).thenReturn(1L);
assertServiceException(() -> dictTypeService.deleteDictType(1L), DICT_TYPE_HAS_CHILDREN);
}
@Test
public void testValidateDictDataExists_success() {
// mock 数据
DictTypeDO dbDictType = randomDictTypeDO();
dictTypeMapper.insert(dbDictType);// @Sql: 先插入出一条存在的数据
void testGetDictTypeList_success() {
List<DictTypeDO> list = List.of(new DictTypeDO(), new DictTypeDO());
when(dictTypeMapper.selectList()).thenReturn(list);
// 调用成功
dictTypeService.validateDictTypeExists(dbDictType.getId());
List<DictTypeDO> result = dictTypeService.getDictTypeList();
assertSame(list, result);
}
@Test
public void testValidateDictDataExists_notExists() {
assertServiceException(() -> dictTypeService.validateDictTypeExists(randomLongId()), DICT_TYPE_NOT_EXISTS);
void validateDictTypeNameUnique_notExists_shouldPass() {
// 模拟数据库返回 null,表示该名字不存在
when(dictTypeMapper.selectByName("newTypeName")).thenReturn(null);
// 调用方法,不应该抛异常
dictTypeService.validateDictTypeNameUnique(null, "newTypeName");
dictTypeService.validateDictTypeNameUnique(1L, "newTypeName");
}
@Test
public void testValidateDictTypeUnique_success() {
// 调用,成功
dictTypeService.validateDictTypeUnique(randomLongId(), randomString());
void validateDictTypeNameUnique_existsWithNullId_shouldThrow() {
// 模拟数据库返回已有记录
DictTypeDO existing = new DictTypeDO();
existing.setId(100L);
when(dictTypeMapper.selectByName("existName")).thenReturn(existing);
assertServiceException(() -> dictTypeService.validateDictTypeNameUnique(null, "existName"), DICT_TYPE_NAME_DUPLICATE);
}
@Test
public void testValidateDictTypeUnique_valueDuplicateForCreate() {
// 准备参数
String type = randomString();
// mock 数据
dictTypeMapper.insert(randomDictTypeDO(o -> o.setType(type)));
void validateDictTypeNameUnique_existsWithDifferentId_shouldThrow() {
// 模拟数据库返回已有记录
DictTypeDO existing = new DictTypeDO();
existing.setId(100L);
when(dictTypeMapper.selectByName("existName")).thenReturn(existing);
// 调用,校验异常
assertServiceException(() -> dictTypeService.validateDictTypeUnique(null, type),
DICT_TYPE_TYPE_DUPLICATE);
assertServiceException(() -> dictTypeService.validateDictTypeNameUnique(200L, "existName"), DICT_TYPE_NAME_DUPLICATE);
}
@Test
public void testValidateDictTypeUnique_valueDuplicateForUpdate() {
// 准备参数
Long id = randomLongId();
String type = randomString();
// mock 数据
dictTypeMapper.insert(randomDictTypeDO(o -> o.setType(type)));
void validateDictTypeNameUnique_existsWithSameId_shouldPass() {
// 模拟数据库返回已有记录
DictTypeDO existing = new DictTypeDO();
existing.setId(100L);
when(dictTypeMapper.selectByName("existName")).thenReturn(existing);
// 调用,校验异常
assertServiceException(() -> dictTypeService.validateDictTypeUnique(id, type),
DICT_TYPE_TYPE_DUPLICATE);
// 当 id 与已有记录一致,不抛异常
dictTypeService.validateDictTypeNameUnique(100L, "existName");
}
@Test
public void testValidateDictTypNameUnique_success() {
// 调用,成功
dictTypeService.validateDictTypeNameUnique(randomLongId(), randomString());
void validateDictTypeUnique_typeNotExists_shouldPass() {
when(dictTypeMapper.selectByType("newType")).thenReturn(null);
dictTypeService.validateDictTypeUnique(1L, "newType");
}
@Test
public void testValidateDictTypeNameUnique_nameDuplicateForCreate() {
// 准备参数
String name = randomString();
// mock 数据
dictTypeMapper.insert(randomDictTypeDO(o -> o.setName(name)));
void validateDictTypeUnique_typeExistsWithNullId_shouldThrow() {
DictTypeDO existing = new DictTypeDO();
existing.setId(100L);
when(dictTypeMapper.selectByType("existType")).thenReturn(existing);
// 调用,校验异常
assertServiceException(() -> dictTypeService.validateDictTypeNameUnique(null, name),
DICT_TYPE_NAME_DUPLICATE);
assertServiceException(() -> dictTypeService.validateDictTypeUnique(null, "existType"), DICT_TYPE_TYPE_DUPLICATE);
}
@Test
public void testValidateDictTypeNameUnique_nameDuplicateForUpdate() {
// 准备参数
Long id = randomLongId();
String name = randomString();
// mock 数据
dictTypeMapper.insert(randomDictTypeDO(o -> o.setName(name)));
void validateDictTypeUnique_typeExistsWithDifferentId_shouldThrow() {
DictTypeDO existing = new DictTypeDO();
existing.setId(100L);
when(dictTypeMapper.selectByType("existType")).thenReturn(existing);
// 调用,校验异常
assertServiceException(() -> dictTypeService.validateDictTypeNameUnique(id, name),
DICT_TYPE_NAME_DUPLICATE);
assertServiceException(() -> dictTypeService.validateDictTypeUnique(200L, "existType"), DICT_TYPE_TYPE_DUPLICATE);
}
// ========== 随机对象 ==========
@Test
void validateDictTypeUnique_typeExistsWithSameId_shouldPass() {
DictTypeDO existing = new DictTypeDO();
existing.setId(100L);
when(dictTypeMapper.selectByType("existType")).thenReturn(existing);
@SafeVarargs
private static DictTypeDO randomDictTypeDO(Consumer<DictTypeDO>... consumers) {
Consumer<DictTypeDO> consumer = (o) -> {
o.setStatus(randomEle(CommonStatusEnum.values()).getStatus()); // 保证 status 的范围
};
return randomPojo(DictTypeDO.class, ArrayUtils.append(consumer, consumers));
dictTypeService.validateDictTypeUnique(100L, "existType");
}
// ================= validateDictTypeExists =================
@Test
void validateDictTypeExists_idNull_shouldReturnNull() {
assertNull(dictTypeService.validateDictTypeExists(null));
}
@Test
void validateDictTypeExists_idNotExists_shouldThrow() {
when(dictTypeMapper.selectById(123L)).thenReturn(null);
assertServiceException(() -> dictTypeService.validateDictTypeExists(123L), DICT_TYPE_NOT_EXISTS);
}
@Test
void validateDictTypeExists_idExists_shouldReturnDictType() {
DictTypeDO dictTypeDO = new DictTypeDO();
dictTypeDO.setId(100L);
when(dictTypeMapper.selectById(100L)).thenReturn(dictTypeDO);
DictTypeDO result = dictTypeService.validateDictTypeExists(100L);
assertSame(dictTypeDO, result);
}
}