mirror of
				https://github.com/YunaiV/ruoyi-vue-pro.git
				synced 2025-10-31 02:28:03 +08:00 
			
		
		
		
	Merge branch 'rouyi/master' into feature/notice_test
# Conflicts: # src/test/resources/sql/create_tables.sql
This commit is contained in:
		| @ -57,7 +57,7 @@ public class DefaultDBFieldHandler implements MetaObjectHandler { | |||||||
|         } |         } | ||||||
|         // 当前登录用户不为空,更新人为空,则当前登录用户为更新人 |         // 当前登录用户不为空,更新人为空,则当前登录用户为更新人 | ||||||
|         if (Objects.nonNull(loginUser) && Objects.isNull(modifier)) { |         if (Objects.nonNull(loginUser) && Objects.isNull(modifier)) { | ||||||
|             setFieldValByName("updater", loginUser.getId(), metaObject); |             setFieldValByName("updater", loginUser.getId().toString(), metaObject); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -25,7 +25,7 @@ public class SysDeptBaseVO { | |||||||
|     private Long parentId; |     private Long parentId; | ||||||
|  |  | ||||||
|     @ApiModelProperty(value = "显示顺序不能为空", required = true, example = "1024") |     @ApiModelProperty(value = "显示顺序不能为空", required = true, example = "1024") | ||||||
|     @NotBlank(message = "显示顺序不能为空") |     @NotNull(message = "显示顺序不能为空") | ||||||
|     private Integer sort; |     private Integer sort; | ||||||
|  |  | ||||||
|     @ApiModelProperty(value = "负责人", example = "芋道") |     @ApiModelProperty(value = "负责人", example = "芋道") | ||||||
|  | |||||||
| @ -4,6 +4,7 @@ import io.swagger.annotations.ApiModelProperty; | |||||||
| import lombok.Data; | import lombok.Data; | ||||||
|  |  | ||||||
| import javax.validation.constraints.NotBlank; | import javax.validation.constraints.NotBlank; | ||||||
|  | import javax.validation.constraints.NotNull; | ||||||
| import javax.validation.constraints.Size; | import javax.validation.constraints.Size; | ||||||
|  |  | ||||||
| /** | /** | ||||||
| @ -24,7 +25,7 @@ public class SysPostBaseVO { | |||||||
|     private String code; |     private String code; | ||||||
|  |  | ||||||
|     @ApiModelProperty(value = "显示顺序不能为空", required = true, example = "1024") |     @ApiModelProperty(value = "显示顺序不能为空", required = true, example = "1024") | ||||||
|     @NotBlank(message = "显示顺序不能为空") |     @NotNull(message = "显示顺序不能为空") | ||||||
|     private Integer sort; |     private Integer sort; | ||||||
|  |  | ||||||
|     @ApiModelProperty(value = "状态", required = true, example = "1", notes = "参见 SysCommonStatusEnum 枚举类") |     @ApiModelProperty(value = "状态", required = true, example = "1", notes = "参见 SysCommonStatusEnum 枚举类") | ||||||
|  | |||||||
| @ -15,7 +15,7 @@ import javax.validation.constraints.Size; | |||||||
| public class SysDictDataBaseVO { | public class SysDictDataBaseVO { | ||||||
|  |  | ||||||
|     @ApiModelProperty(value = "显示顺序不能为空", required = true, example = "1024") |     @ApiModelProperty(value = "显示顺序不能为空", required = true, example = "1024") | ||||||
|     @NotBlank(message = "显示顺序不能为空") |     @NotNull(message = "显示顺序不能为空") | ||||||
|     private Integer sort; |     private Integer sort; | ||||||
|  |  | ||||||
|     @ApiModelProperty(value = "字典标签", required = true, example = "芋道") |     @ApiModelProperty(value = "字典标签", required = true, example = "芋道") | ||||||
|  | |||||||
| @ -28,7 +28,7 @@ public class SysMenuBaseVO { | |||||||
|     private Integer type; |     private Integer type; | ||||||
|  |  | ||||||
|     @ApiModelProperty(value = "显示顺序不能为空", required = true, example = "1024") |     @ApiModelProperty(value = "显示顺序不能为空", required = true, example = "1024") | ||||||
|     @NotBlank(message = "显示顺序不能为空") |     @NotNull(message = "显示顺序不能为空") | ||||||
|     private Integer sort; |     private Integer sort; | ||||||
|  |  | ||||||
|     @ApiModelProperty(value = "父菜单 ID", required = true, example = "1024") |     @ApiModelProperty(value = "父菜单 ID", required = true, example = "1024") | ||||||
|  | |||||||
| @ -4,6 +4,7 @@ import io.swagger.annotations.ApiModelProperty; | |||||||
| import lombok.Data; | import lombok.Data; | ||||||
|  |  | ||||||
| import javax.validation.constraints.NotBlank; | import javax.validation.constraints.NotBlank; | ||||||
|  | import javax.validation.constraints.NotNull; | ||||||
| import javax.validation.constraints.Size; | import javax.validation.constraints.Size; | ||||||
|  |  | ||||||
| /** | /** | ||||||
| @ -24,7 +25,7 @@ public class SysRoleBaseVO { | |||||||
|     private String code; |     private String code; | ||||||
|  |  | ||||||
|     @ApiModelProperty(value = "显示顺序不能为空", required = true, example = "1024") |     @ApiModelProperty(value = "显示顺序不能为空", required = true, example = "1024") | ||||||
|     @NotBlank(message = "显示顺序不能为空") |     @NotNull(message = "显示顺序不能为空") | ||||||
|     private Integer sort; |     private Integer sort; | ||||||
|  |  | ||||||
|     @ApiModelProperty(value = "角色类型", required = true, example = "1", notes = "见 SysRoleTypeEnum 枚举") |     @ApiModelProperty(value = "角色类型", required = true, example = "1", notes = "见 SysRoleTypeEnum 枚举") | ||||||
|  | |||||||
| @ -0,0 +1,274 @@ | |||||||
|  | package cn.iocoder.dashboard.modules.system.service.dept; | ||||||
|  |  | ||||||
|  | import cn.iocoder.dashboard.BaseDbUnitTest; | ||||||
|  | import cn.iocoder.dashboard.common.enums.CommonStatusEnum; | ||||||
|  | import cn.iocoder.dashboard.modules.system.controller.dept.vo.dept.SysDeptCreateReqVO; | ||||||
|  | import cn.iocoder.dashboard.modules.system.controller.dept.vo.dept.SysDeptListReqVO; | ||||||
|  | import cn.iocoder.dashboard.modules.system.controller.dept.vo.dept.SysDeptUpdateReqVO; | ||||||
|  | import cn.iocoder.dashboard.modules.system.dal.dataobject.dept.SysDeptDO; | ||||||
|  | import cn.iocoder.dashboard.modules.system.dal.mysql.dept.SysDeptMapper; | ||||||
|  | import cn.iocoder.dashboard.modules.system.enums.dept.DeptIdEnum; | ||||||
|  | import cn.iocoder.dashboard.modules.system.mq.producer.dept.SysDeptProducer; | ||||||
|  | import cn.iocoder.dashboard.modules.system.service.dept.impl.SysDeptServiceImpl; | ||||||
|  | import cn.iocoder.dashboard.util.collection.ArrayUtils; | ||||||
|  | import cn.iocoder.dashboard.util.object.ObjectUtils; | ||||||
|  | import com.google.common.collect.Multimap; | ||||||
|  | import org.junit.jupiter.api.Test; | ||||||
|  | import org.springframework.boot.test.mock.mockito.MockBean; | ||||||
|  | import org.springframework.context.annotation.Import; | ||||||
|  |  | ||||||
|  | import javax.annotation.Resource; | ||||||
|  | import java.util.Date; | ||||||
|  | import java.util.List; | ||||||
|  | import java.util.Map; | ||||||
|  | import java.util.function.Consumer; | ||||||
|  |  | ||||||
|  | import static cn.hutool.core.bean.BeanUtil.getFieldValue; | ||||||
|  | import static cn.hutool.core.util.RandomUtil.randomEle; | ||||||
|  | import static cn.iocoder.dashboard.modules.system.enums.SysErrorCodeConstants.*; | ||||||
|  | import static cn.iocoder.dashboard.util.AssertUtils.assertPojoEquals; | ||||||
|  | import static cn.iocoder.dashboard.util.AssertUtils.assertServiceException; | ||||||
|  | import static cn.iocoder.dashboard.util.RandomUtils.*; | ||||||
|  | import static org.junit.jupiter.api.Assertions.*; | ||||||
|  | import static org.mockito.Mockito.times; | ||||||
|  | import static org.mockito.Mockito.verify; | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * {@link SysDeptServiceImpl} 的单元测试类 | ||||||
|  |  * | ||||||
|  |  * @author niudehua | ||||||
|  |  */ | ||||||
|  | @Import(SysDeptServiceImpl.class) | ||||||
|  | class SysDeptServiceTest extends BaseDbUnitTest { | ||||||
|  |  | ||||||
|  |     @Resource | ||||||
|  |     private SysDeptServiceImpl deptService; | ||||||
|  |     @Resource | ||||||
|  |     private SysDeptMapper deptMapper; | ||||||
|  |     @MockBean | ||||||
|  |     private SysDeptProducer deptProducer; | ||||||
|  |  | ||||||
|  |     @Test | ||||||
|  |     @SuppressWarnings("unchecked") | ||||||
|  |     void testInitLocalCache() { | ||||||
|  |         // mock 数据 | ||||||
|  |         SysDeptDO deptDO1 = randomDeptDO(); | ||||||
|  |         deptMapper.insert(deptDO1); | ||||||
|  |         SysDeptDO deptDO2 = randomDeptDO(); | ||||||
|  |         deptMapper.insert(deptDO2); | ||||||
|  |  | ||||||
|  |         // 调用 | ||||||
|  |         deptService.initLocalCache(); | ||||||
|  |         // 断言 deptCache 缓存 | ||||||
|  |         Map<Long, SysDeptDO> deptCache = (Map<Long, SysDeptDO>) getFieldValue(deptService, "deptCache"); | ||||||
|  |         assertEquals(2, deptCache.size()); | ||||||
|  |         assertPojoEquals(deptDO1, deptCache.get(deptDO1.getId())); | ||||||
|  |         assertPojoEquals(deptDO2, deptCache.get(deptDO2.getId())); | ||||||
|  |         // 断言 parentDeptCache 缓存 | ||||||
|  |         Multimap<Long, SysDeptDO> parentDeptCache = (Multimap<Long, SysDeptDO>) getFieldValue(deptService, "parentDeptCache"); | ||||||
|  |         assertEquals(2, parentDeptCache.size()); | ||||||
|  |         assertPojoEquals(deptDO1, parentDeptCache.get(deptDO1.getParentId())); | ||||||
|  |         assertPojoEquals(deptDO2, parentDeptCache.get(deptDO2.getParentId())); | ||||||
|  |         // 断言 maxUpdateTime 缓存 | ||||||
|  |         Date maxUpdateTime = (Date) getFieldValue(deptService, "maxUpdateTime"); | ||||||
|  |         assertEquals(ObjectUtils.max(deptDO1.getUpdateTime(), deptDO2.getUpdateTime()), maxUpdateTime); | ||||||
|  |  | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Test | ||||||
|  |     void testListDepts() { | ||||||
|  |         // mock 数据 | ||||||
|  |         SysDeptDO dept = randomPojo(SysDeptDO.class, o -> { // 等会查询到 | ||||||
|  |             o.setName("开发部"); | ||||||
|  |             o.setStatus(CommonStatusEnum.ENABLE.getStatus()); | ||||||
|  |         }); | ||||||
|  |         deptMapper.insert(dept); | ||||||
|  |         // 测试 name 不匹配 | ||||||
|  |         deptMapper.insert(ObjectUtils.clone(dept, o -> o.setName("发"))); | ||||||
|  |         // 测试 status 不匹配 | ||||||
|  |         deptMapper.insert(ObjectUtils.clone(dept, o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus()))); | ||||||
|  |         // 准备参数 | ||||||
|  |         SysDeptListReqVO reqVO = new SysDeptListReqVO(); | ||||||
|  |         reqVO.setName("开"); | ||||||
|  |         reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus()); | ||||||
|  |         // 调用 | ||||||
|  |         List<SysDeptDO> sysDeptDOS = deptService.listDepts(reqVO); | ||||||
|  |         // 断言 | ||||||
|  |         assertEquals(1, sysDeptDOS.size()); | ||||||
|  |         assertPojoEquals(dept, sysDeptDOS.get(0)); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Test | ||||||
|  |     void testCreateDept_success() { | ||||||
|  |         // 准备参数 | ||||||
|  |         SysDeptCreateReqVO reqVO = randomPojo(SysDeptCreateReqVO.class, | ||||||
|  |             o -> { | ||||||
|  |                 o.setParentId(DeptIdEnum.ROOT.getId()); | ||||||
|  |                 o.setStatus(randomCommonStatus()); | ||||||
|  |             }); | ||||||
|  |         // 调用 | ||||||
|  |         Long deptId = deptService.createDept(reqVO); | ||||||
|  |         // 断言 | ||||||
|  |         assertNotNull(deptId); | ||||||
|  |         // 校验记录的属性是否正确 | ||||||
|  |         SysDeptDO deptDO = deptMapper.selectById(deptId); | ||||||
|  |         assertPojoEquals(reqVO, deptDO); | ||||||
|  |         // 校验调用 | ||||||
|  |         verify(deptProducer, times(1)).sendDeptRefreshMessage(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Test | ||||||
|  |     void testUpdateDept_success() { | ||||||
|  |         // mock 数据 | ||||||
|  |         SysDeptDO dbDeptDO = randomPojo(SysDeptDO.class, o -> o.setStatus(randomCommonStatus())); | ||||||
|  |         deptMapper.insert(dbDeptDO);// @Sql: 先插入出一条存在的数据 | ||||||
|  |         // 准备参数 | ||||||
|  |         SysDeptUpdateReqVO reqVO = randomPojo(SysDeptUpdateReqVO.class, o -> { | ||||||
|  |             // 设置更新的 ID | ||||||
|  |             o.setParentId(DeptIdEnum.ROOT.getId()); | ||||||
|  |             o.setId(dbDeptDO.getId()); | ||||||
|  |             o.setStatus(randomCommonStatus()); | ||||||
|  |         }); | ||||||
|  |         // 调用 | ||||||
|  |         deptService.updateDept(reqVO); | ||||||
|  |         // 校验是否更新正确 | ||||||
|  |         SysDeptDO deptDO = deptMapper.selectById(reqVO.getId()); // 获取最新的 | ||||||
|  |         assertPojoEquals(reqVO, deptDO); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Test | ||||||
|  |     void testDeleteDept_success() { | ||||||
|  |         // mock 数据 | ||||||
|  |         SysDeptDO dbDeptDO = randomPojo(SysDeptDO.class, o -> o.setStatus(randomCommonStatus())); | ||||||
|  |         deptMapper.insert(dbDeptDO);// @Sql: 先插入出一条存在的数据 | ||||||
|  |         // 准备参数 | ||||||
|  |         Long id = dbDeptDO.getId(); | ||||||
|  |         // 调用 | ||||||
|  |         deptService.deleteDept(id); | ||||||
|  |         // 校验数据不存在了 | ||||||
|  |         assertNull(deptMapper.selectById(id)); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Test | ||||||
|  |     void testCheckDept_nameDuplicateForUpdate() { | ||||||
|  |         // mock 数据 | ||||||
|  |         SysDeptDO deptDO = randomDeptDO(); | ||||||
|  |         // 设置根节点部门 | ||||||
|  |         deptDO.setParentId(DeptIdEnum.ROOT.getId()); | ||||||
|  |         deptMapper.insert(deptDO); | ||||||
|  |         // mock 数据 稍后模拟重复它的 name | ||||||
|  |         SysDeptDO nameDeptDO = randomDeptDO(); | ||||||
|  |         // 设置根节点部门 | ||||||
|  |         nameDeptDO.setParentId(DeptIdEnum.ROOT.getId()); | ||||||
|  |         deptMapper.insert(nameDeptDO); | ||||||
|  |         // 准备参数 | ||||||
|  |         SysDeptUpdateReqVO reqVO = randomPojo(SysDeptUpdateReqVO.class, | ||||||
|  |             o -> { | ||||||
|  |                 // 设置根节点部门 | ||||||
|  |                 o.setParentId(DeptIdEnum.ROOT.getId()); | ||||||
|  |                 // 设置更新的 ID | ||||||
|  |                 o.setId(deptDO.getId()); | ||||||
|  |                 // 模拟 name 重复 | ||||||
|  |                 o.setName(nameDeptDO.getName()); | ||||||
|  |             }); | ||||||
|  |         // 调用, 并断言异常 | ||||||
|  |         assertServiceException(() -> deptService.updateDept(reqVO), DEPT_NAME_DUPLICATE); | ||||||
|  |  | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Test | ||||||
|  |     void testCheckDept_parentNotExitsForCreate() { | ||||||
|  |         SysDeptCreateReqVO reqVO = randomPojo(SysDeptCreateReqVO.class, | ||||||
|  |             o -> o.setStatus(randomCommonStatus())); | ||||||
|  |         // 调用,并断言异常 | ||||||
|  |         assertServiceException(() -> deptService.createDept(reqVO), DEPT_PARENT_NOT_EXITS); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Test | ||||||
|  |     void testCheckDept_notFoundForDelete() { | ||||||
|  |         // 准备参数 | ||||||
|  |         Long id = randomLongId(); | ||||||
|  |         // 调用, 并断言异常 | ||||||
|  |         assertServiceException(() -> deptService.deleteDept(id), DEPT_NOT_FOUND); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Test | ||||||
|  |     void testCheckDept_exitsChildrenForDelete() { | ||||||
|  |         // mock 数据 | ||||||
|  |         SysDeptDO parentDept = randomPojo(SysDeptDO.class, o -> o.setStatus(randomCommonStatus())); | ||||||
|  |         deptMapper.insert(parentDept);// @Sql: 先插入出一条存在的数据 | ||||||
|  |         // 准备参数 | ||||||
|  |         SysDeptDO childrenDeptDO = randomPojo(SysDeptDO.class, o -> { | ||||||
|  |             o.setParentId(parentDept.getId()); | ||||||
|  |             o.setStatus(randomCommonStatus()); | ||||||
|  |         }); | ||||||
|  |         // 插入子部门 | ||||||
|  |         deptMapper.insert(childrenDeptDO); | ||||||
|  |         // 调用, 并断言异常 | ||||||
|  |         assertServiceException(() -> deptService.deleteDept(parentDept.getId()), DEPT_EXITS_CHILDREN); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Test | ||||||
|  |     void testCheckDept_parentErrorForUpdate() { | ||||||
|  |         // mock 数据 | ||||||
|  |         SysDeptDO dbDeptDO = randomPojo(SysDeptDO.class, o -> o.setStatus(randomCommonStatus())); | ||||||
|  |         deptMapper.insert(dbDeptDO); | ||||||
|  |         // 准备参数 | ||||||
|  |         SysDeptUpdateReqVO reqVO = randomPojo(SysDeptUpdateReqVO.class, | ||||||
|  |             o -> { | ||||||
|  |                 // 设置自己为父部门 | ||||||
|  |                 o.setParentId(dbDeptDO.getId()); | ||||||
|  |                 // 设置更新的 ID | ||||||
|  |                 o.setId(dbDeptDO.getId()); | ||||||
|  |             }); | ||||||
|  |         // 调用, 并断言异常 | ||||||
|  |         assertServiceException(() -> deptService.updateDept(reqVO), DEPT_PARENT_ERROR); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Test | ||||||
|  |     void testCheckDept_notEnableForCreate() { | ||||||
|  |         // mock 数据 | ||||||
|  |         SysDeptDO deptDO = randomPojo(SysDeptDO.class, o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus())); | ||||||
|  |         deptMapper.insert(deptDO); | ||||||
|  |         // 准备参数 | ||||||
|  |         SysDeptCreateReqVO reqVO = randomPojo(SysDeptCreateReqVO.class, | ||||||
|  |             o -> { | ||||||
|  |                 // 设置未启用的部门为副部门 | ||||||
|  |                 o.setParentId(deptDO.getId()); | ||||||
|  |             }); | ||||||
|  |         // 调用, 并断言异常 | ||||||
|  |         assertServiceException(() -> deptService.createDept(reqVO), DEPT_NOT_ENABLE); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Test | ||||||
|  |     void testCheckDept_parentIsChildForUpdate() { | ||||||
|  |         // mock 数据 | ||||||
|  |         SysDeptDO parentDept = randomPojo(SysDeptDO.class, o -> o.setStatus(CommonStatusEnum.ENABLE.getStatus())); | ||||||
|  |         deptMapper.insert(parentDept); | ||||||
|  |         SysDeptDO childDept = randomPojo(SysDeptDO.class, o -> { | ||||||
|  |             o.setStatus(CommonStatusEnum.ENABLE.getStatus()); | ||||||
|  |             o.setParentId(parentDept.getId()); | ||||||
|  |         }); | ||||||
|  |         deptMapper.insert(childDept); | ||||||
|  |         // 初始化本地缓存 | ||||||
|  |         deptService.initLocalCache(); | ||||||
|  |         // 准备参数 | ||||||
|  |         SysDeptUpdateReqVO reqVO = randomPojo(SysDeptUpdateReqVO.class, | ||||||
|  |             o -> { | ||||||
|  |                 // 设置自己的子部门为父部门 | ||||||
|  |                 o.setParentId(childDept.getId()); | ||||||
|  |                 // 设置更新的 ID | ||||||
|  |                 o.setId(parentDept.getId()); | ||||||
|  |             }); | ||||||
|  |         // 调用, 并断言异常 | ||||||
|  |         assertServiceException(() -> deptService.updateDept(reqVO), DEPT_PARENT_IS_CHILD); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @SafeVarargs | ||||||
|  |     private static SysDeptDO randomDeptDO(Consumer<SysDeptDO>... consumers) { | ||||||
|  |         Consumer<SysDeptDO> consumer = (o) -> { | ||||||
|  |             o.setStatus(randomEle(CommonStatusEnum.values()).getStatus()); // 保证 status 的范围 | ||||||
|  |         }; | ||||||
|  |         return randomPojo(SysDeptDO.class, ArrayUtils.append(consumer, consumers)); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,200 @@ | |||||||
|  | package cn.iocoder.dashboard.modules.system.service.dept; | ||||||
|  |  | ||||||
|  | import cn.iocoder.dashboard.BaseDbUnitTest; | ||||||
|  | import cn.iocoder.dashboard.common.enums.CommonStatusEnum; | ||||||
|  | import cn.iocoder.dashboard.common.pojo.PageResult; | ||||||
|  | import cn.iocoder.dashboard.modules.system.controller.dept.vo.post.SysPostCreateReqVO; | ||||||
|  | import cn.iocoder.dashboard.modules.system.controller.dept.vo.post.SysPostExportReqVO; | ||||||
|  | import cn.iocoder.dashboard.modules.system.controller.dept.vo.post.SysPostPageReqVO; | ||||||
|  | import cn.iocoder.dashboard.modules.system.controller.dept.vo.post.SysPostUpdateReqVO; | ||||||
|  | import cn.iocoder.dashboard.modules.system.dal.dataobject.dept.SysPostDO; | ||||||
|  | import cn.iocoder.dashboard.modules.system.dal.mysql.dept.SysPostMapper; | ||||||
|  | import cn.iocoder.dashboard.modules.system.service.dept.impl.SysPostServiceImpl; | ||||||
|  | import cn.iocoder.dashboard.util.collection.ArrayUtils; | ||||||
|  | import cn.iocoder.dashboard.util.object.ObjectUtils; | ||||||
|  | import org.junit.jupiter.api.Test; | ||||||
|  | import org.springframework.context.annotation.Import; | ||||||
|  |  | ||||||
|  | import javax.annotation.Resource; | ||||||
|  | import java.util.List; | ||||||
|  | import java.util.function.Consumer; | ||||||
|  |  | ||||||
|  | import static cn.hutool.core.util.RandomUtil.randomEle; | ||||||
|  | import static cn.iocoder.dashboard.modules.system.enums.SysErrorCodeConstants.*; | ||||||
|  | import static cn.iocoder.dashboard.util.AssertUtils.assertPojoEquals; | ||||||
|  | import static cn.iocoder.dashboard.util.AssertUtils.assertServiceException; | ||||||
|  | import static cn.iocoder.dashboard.util.RandomUtils.randomLongId; | ||||||
|  | import static cn.iocoder.dashboard.util.RandomUtils.randomPojo; | ||||||
|  | import static org.junit.jupiter.api.Assertions.*; | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * {@link SysPostServiceImpl} 的单元测试类 | ||||||
|  |  * | ||||||
|  |  * @author niudehua | ||||||
|  |  */ | ||||||
|  | @Import(SysPostServiceImpl.class) | ||||||
|  | class SysPostServiceTest extends BaseDbUnitTest { | ||||||
|  |  | ||||||
|  |     @Resource | ||||||
|  |     private SysPostServiceImpl postService; | ||||||
|  |     @Resource | ||||||
|  |     private SysPostMapper postMapper; | ||||||
|  |  | ||||||
|  |     @Test | ||||||
|  |     void testPagePosts() { | ||||||
|  |         // mock 数据 | ||||||
|  |         SysPostDO postDO = randomPojo(SysPostDO.class, o -> { | ||||||
|  |             o.setName("码仔"); | ||||||
|  |             o.setStatus(CommonStatusEnum.ENABLE.getStatus()); | ||||||
|  |         }); | ||||||
|  |         postMapper.insert(postDO); | ||||||
|  |         // 测试 name 不匹配 | ||||||
|  |         postMapper.insert(ObjectUtils.clone(postDO, o -> o.setName("程序员"))); | ||||||
|  |         // 测试 status 不匹配 | ||||||
|  |         postMapper.insert(ObjectUtils.clone(postDO, o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus()))); | ||||||
|  |  | ||||||
|  |         // 准备参数 | ||||||
|  |         SysPostPageReqVO reqVO = new SysPostPageReqVO(); | ||||||
|  |         reqVO.setName("码"); | ||||||
|  |         reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus()); | ||||||
|  |  | ||||||
|  |         // 调用 | ||||||
|  |         PageResult<SysPostDO> pageResult = postService.pagePosts(reqVO); | ||||||
|  |  | ||||||
|  |         // 断言 | ||||||
|  |         assertEquals(1, pageResult.getTotal()); | ||||||
|  |         assertEquals(1, pageResult.getList().size()); | ||||||
|  |         assertPojoEquals(postDO, pageResult.getList().get(0)); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Test | ||||||
|  |     void testListPosts() { | ||||||
|  |         // mock 数据 | ||||||
|  |         SysPostDO postDO = randomPojo(SysPostDO.class, o -> { | ||||||
|  |             o.setName("码仔"); | ||||||
|  |             o.setStatus(CommonStatusEnum.ENABLE.getStatus()); | ||||||
|  |         }); | ||||||
|  |         postMapper.insert(postDO); | ||||||
|  |         // 测试 name 不匹配 | ||||||
|  |         postMapper.insert(ObjectUtils.clone(postDO, o -> o.setName("程序员"))); | ||||||
|  |         // 测试 status 不匹配 | ||||||
|  |         postMapper.insert(ObjectUtils.clone(postDO, o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus()))); | ||||||
|  |         // 准备参数 | ||||||
|  |         SysPostExportReqVO reqVO = new SysPostExportReqVO(); | ||||||
|  |         reqVO.setName("码"); | ||||||
|  |         reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus()); | ||||||
|  |  | ||||||
|  |         // 调用 | ||||||
|  |         List<SysPostDO> list = postService.listPosts(reqVO); | ||||||
|  |         // 断言 | ||||||
|  |         assertEquals(1, list.size()); | ||||||
|  |         assertPojoEquals(postDO, list.get(0)); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Test | ||||||
|  |     void testGetPost() { | ||||||
|  |         // mock 数据 | ||||||
|  |         SysPostDO dbPostDO = randomPostDO(); | ||||||
|  |         postMapper.insert(dbPostDO); | ||||||
|  |         // 准备参数 | ||||||
|  |         Long id = dbPostDO.getId(); | ||||||
|  |         // 调用 | ||||||
|  |         SysPostDO post = postService.getPost(id); | ||||||
|  |         // 断言 | ||||||
|  |         assertNotNull(post); | ||||||
|  |         assertPojoEquals(dbPostDO, post); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Test | ||||||
|  |     void testCreatePost_success() { | ||||||
|  |         // 准备参数 | ||||||
|  |         SysPostCreateReqVO reqVO = randomPojo(SysPostCreateReqVO.class, | ||||||
|  |             o -> o.setStatus(randomEle(CommonStatusEnum.values()).getStatus())); | ||||||
|  |         // 调用 | ||||||
|  |         Long postId = postService.createPost(reqVO); | ||||||
|  |         // 断言 | ||||||
|  |         assertNotNull(postId); | ||||||
|  |         // 校验记录的属性是否正确 | ||||||
|  |         SysPostDO post = postMapper.selectById(postId); | ||||||
|  |         assertPojoEquals(reqVO, post); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Test | ||||||
|  |     void testUpdatePost_success() { | ||||||
|  |         // mock 数据 | ||||||
|  |         SysPostDO postDO = randomPostDO(); | ||||||
|  |         postMapper.insert(postDO);// @Sql: 先插入出一条存在的数据 | ||||||
|  |         // 准备参数 | ||||||
|  |         SysPostUpdateReqVO reqVO = randomPojo(SysPostUpdateReqVO.class, | ||||||
|  |             o -> { | ||||||
|  |                 // 设置更新的 ID | ||||||
|  |                 o.setId(postDO.getId()); | ||||||
|  |                 o.setStatus(randomEle(CommonStatusEnum.values()).getStatus()); | ||||||
|  |             }); | ||||||
|  |         // 调用 | ||||||
|  |         postService.updatePost(reqVO); | ||||||
|  |         // 校验是否更新正确 | ||||||
|  |         SysPostDO post = postMapper.selectById(reqVO.getId());// 获取最新的 | ||||||
|  |         assertPojoEquals(reqVO, post); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Test | ||||||
|  |     void testDeletePost_success() { | ||||||
|  |         // mock 数据 | ||||||
|  |         SysPostDO postDO = randomPostDO(); | ||||||
|  |         postMapper.insert(postDO); | ||||||
|  |         // 准备参数 | ||||||
|  |         Long id = postDO.getId(); | ||||||
|  |         // 调用 | ||||||
|  |         postService.deletePost(id); | ||||||
|  |         assertNull(postMapper.selectById(id)); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Test | ||||||
|  |     void testCheckPost_notFoundForDelete() { | ||||||
|  |         // 准备参数 | ||||||
|  |         Long id = randomLongId(); | ||||||
|  |         // 调用, 并断言异常 | ||||||
|  |         assertServiceException(() -> postService.deletePost(id), POST_NOT_FOUND); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Test | ||||||
|  |     void testCheckPost_nameDuplicateForCreate() { | ||||||
|  |         // mock 数据 | ||||||
|  |         SysPostDO postDO = randomPostDO(); | ||||||
|  |         postMapper.insert(postDO);// @Sql: 先插入出一条存在的数据 | ||||||
|  |         // 准备参数 | ||||||
|  |         SysPostCreateReqVO reqVO = randomPojo(SysPostCreateReqVO.class, | ||||||
|  |             // 模拟 name 重复 | ||||||
|  |             o -> o.setName(postDO.getName())); | ||||||
|  |         assertServiceException(() -> postService.createPost(reqVO), POST_NAME_DUPLICATE); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Test | ||||||
|  |     void testCheckPost_codeDuplicateForUpdate() { | ||||||
|  |         // mock 数据 | ||||||
|  |         SysPostDO postDO = randomPostDO(); | ||||||
|  |         postMapper.insert(postDO); | ||||||
|  |         // mock 数据 稍后模拟重复它的 code | ||||||
|  |         SysPostDO codePostDO = randomPostDO(); | ||||||
|  |         postMapper.insert(codePostDO); | ||||||
|  |         // 准备参数 | ||||||
|  |         SysPostUpdateReqVO reqVO = randomPojo(SysPostUpdateReqVO.class, | ||||||
|  |             o -> { | ||||||
|  |                 // 设置更新的 ID | ||||||
|  |                 o.setId(postDO.getId()); | ||||||
|  |                 // 模拟 code 重复 | ||||||
|  |                 o.setCode(codePostDO.getCode()); | ||||||
|  |             }); | ||||||
|  |         // 调用, 并断言异常 | ||||||
|  |         assertServiceException(() -> postService.updatePost(reqVO), POST_CODE_DUPLICATE); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @SafeVarargs | ||||||
|  |     private static SysPostDO randomPostDO(Consumer<SysPostDO>... consumers) { | ||||||
|  |         Consumer<SysPostDO> consumer = (o) -> { | ||||||
|  |             o.setStatus(randomEle(CommonStatusEnum.values()).getStatus()); // 保证 status 的范围 | ||||||
|  |         }; | ||||||
|  |         return randomPojo(SysPostDO.class, ArrayUtils.append(consumer, consumers)); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -9,3 +9,4 @@ DELETE FROM "sys_role_menu"; | |||||||
| DELETE FROM "sys_menu"; | DELETE FROM "sys_menu"; | ||||||
| DELETE FROM "sys_dict_type"; | DELETE FROM "sys_dict_type"; | ||||||
| DELETE FROM "sys_user_session"; | DELETE FROM "sys_user_session"; | ||||||
|  | DELETE FROM "sys_post"; | ||||||
|  | |||||||
| @ -130,6 +130,23 @@ CREATE TABLE `sys_user_session` ( | |||||||
|     PRIMARY KEY (`id`) |     PRIMARY KEY (`id`) | ||||||
| ) COMMENT '用户在线 Session'; | ) COMMENT '用户在线 Session'; | ||||||
|  |  | ||||||
|  | CREATE TABLE IF NOT EXISTS "sys_post" | ||||||
|  | ( | ||||||
|  |     "id"          bigint      NOT NULL GENERATED BY DEFAULT AS IDENTITY, | ||||||
|  |     "code"        varchar(64) NOT NULL, | ||||||
|  |     "name"        varchar(50) NOT NULL, | ||||||
|  |     "sort"        integer     NOT NULL, | ||||||
|  |     "status"      tinyint     NOT NULL, | ||||||
|  |     "remark"      varchar(500)         DEFAULT NULL, | ||||||
|  |     "creator"     varchar(64)          DEFAULT '', | ||||||
|  |     "create_time" timestamp   NOT NULL DEFAULT CURRENT_TIMESTAMP, | ||||||
|  |     "updater"     varchar(64)          DEFAULT '', | ||||||
|  |     "update_time" timestamp   NOT NULL DEFAULT CURRENT_TIMESTAMP, | ||||||
|  |     "deleted"     bit         NOT NULL DEFAULT FALSE, | ||||||
|  |     PRIMARY KEY ("id") | ||||||
|  | ) COMMENT '岗位信息表'; | ||||||
|  |  | ||||||
|  |  | ||||||
| CREATE TABLE IF NOT EXISTS "sys_notice" ( | CREATE TABLE IF NOT EXISTS "sys_notice" ( | ||||||
| 	"id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY, | 	"id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY, | ||||||
| 	"title" varchar(50) NOT NULL COMMENT '公告标题', | 	"title" varchar(50) NOT NULL COMMENT '公告标题', | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user
	 budliang
					budliang