!13 user模块单元测试

Merge pull request !13 from 化身孤岛的鲸/feat_test-user
This commit is contained in:
芋道源码 2021-04-18 13:43:55 +08:00 committed by Gitee
commit 4a322ed72a
11 changed files with 662 additions and 65 deletions

15
pom.xml
View File

@ -46,7 +46,12 @@
<easyexcel.verion>2.2.7</easyexcel.verion>
<velocity.version>2.2</velocity.version>
<screw.version>1.0.5</screw.version>
<podam.version>7.2.6.RELEASE</podam.version>
<jedis-mock.version>0.1.16</jedis-mock.version>
<!-- 三方云服务相关 -->
<aliyun-java-sdk-core.version>4.5.18</aliyun-java-sdk-core.version>
<aliyun-java-sdk-dysmsapi.version>2.1.0</aliyun-java-sdk-dysmsapi.version>
<yunpian-java-sdk.version>1.2.7</yunpian-java-sdk.version>
</properties>
<!-- 依赖声明 -->
@ -213,14 +218,14 @@
<dependency>
<groupId>com.github.fppt</groupId> <!-- 单元测试,我们采用内嵌的 Redis 数据库 -->
<artifactId>jedis-mock</artifactId>
<version>0.1.16</version>
<version>${jedis-mock.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>uk.co.jemos.podam</groupId> <!-- 单元测试,随机生成 POJO 类 -->
<artifactId>podam</artifactId>
<version>7.2.6.RELEASE</version>
<version>${podam.version}</version>
<scope>test</scope>
</dependency>
@ -278,18 +283,18 @@
<dependency>
<groupId>com.yunpian.sdk</groupId>
<artifactId>yunpian-java-sdk</artifactId>
<version>1.2.7</version>
<version>${yunpian-java-sdk.version}</version>
</dependency>
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-core</artifactId>
<version>4.5.18</version>
<version>${aliyun-java-sdk-core.version}</version>
</dependency>
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-dysmsapi</artifactId>
<version>2.1.0</version>
<version>${aliyun-java-sdk-dysmsapi.version}</version>
</dependency>
<!-- SMS SDK end -->

View File

@ -362,7 +362,7 @@ export default {
created() {
this.getList();
this.getTreeselect();
this.getConfigKey("sys.user.initPassword").then(response => {
this.getConfigKey("sys.user.init-password").then(response => {
this.initPassword = response.msg;
});
},

View File

@ -149,9 +149,9 @@ public class SysUserController {
// 手动创建导出 demo
List<SysUserImportExcelVO> list = Arrays.asList(
SysUserImportExcelVO.builder().username("yudao").deptId(1L).email("yudao@iocoder.cn").mobile("15601691300")
.nickname("芋道").status(CommonStatusEnum.ENABLE.getStatus()).sex(SysSexEnum.MALE.getSEX()).build(),
.nickname("芋道").status(CommonStatusEnum.ENABLE.getStatus()).sex(SysSexEnum.MALE.getSex()).build(),
SysUserImportExcelVO.builder().username("yuanma").deptId(2L).email("yuanma@iocoder.cn").mobile("15601701300")
.nickname("源码").status(CommonStatusEnum.DISABLE.getStatus()).sex(SysSexEnum.FEMALE.getSEX()).build()
.nickname("源码").status(CommonStatusEnum.DISABLE.getStatus()).sex(SysSexEnum.FEMALE.getSex()).build()
);
// 输出

View File

@ -3,9 +3,9 @@ package cn.iocoder.dashboard.modules.system.controller.user.vo.profile;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.hibernate.validator.constraints.Length;
import javax.validation.constraints.Email;
import javax.validation.constraints.Pattern;
import javax.validation.constraints.Size;
@ApiModel("用户个人信息更新 Request VO")
@ -22,7 +22,7 @@ public class SysUserProfileUpdateReqVO {
private String email;
@ApiModelProperty(value = "手机号码", example = "15601691300")
@Pattern(regexp = "^1(3|4|5|7|8)\\d{9}$",message = "手机号码格式错误")
@Length(min = 11, max = 11, message = "手机号长度必须 11 位")
private String mobile;
@ApiModelProperty(value = "用户性别", example = "1", notes = "参见 SysSexEnum 枚举类")

View File

@ -2,10 +2,10 @@ package cn.iocoder.dashboard.modules.system.controller.user.vo.user;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.hibernate.validator.constraints.Length;
import javax.validation.constraints.Email;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Pattern;
import javax.validation.constraints.Size;
import java.util.Set;
@ -40,7 +40,7 @@ public class SysUserBaseVO {
private String email;
@ApiModelProperty(value = "手机号码", example = "15601691300")
@Pattern(regexp = "^1(3|4|5|7|8)\\d{9}$",message = "手机号码格式错误")
@Length(min = 11, max = 11, message = "手机号长度必须 11 位")
private String mobile;
@ApiModelProperty(value = "用户性别", example = "1", notes = "参见 SysSexEnum 枚举类")

View File

@ -3,6 +3,11 @@ package cn.iocoder.dashboard.modules.system.enums.common;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* 性别的枚举值
*
* @author 芋道源码
*/
@Getter
@AllArgsConstructor
public enum SysSexEnum {
@ -10,6 +15,9 @@ public enum SysSexEnum {
MALE(1), //
FEMALE(2); //
private final Integer SEX;
/**
* 性别
*/
private final Integer sex;
}

View File

@ -6,17 +6,11 @@ import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import cn.iocoder.dashboard.common.enums.CommonStatusEnum;
import cn.iocoder.dashboard.common.exception.ServiceException;
import cn.iocoder.dashboard.common.exception.util.ServiceExceptionUtil;
import cn.iocoder.dashboard.common.pojo.PageResult;
import cn.iocoder.dashboard.modules.infra.service.file.InfFileService;
import cn.iocoder.dashboard.modules.system.controller.user.vo.profile.SysUserProfileUpdatePasswordReqVO;
import cn.iocoder.dashboard.modules.system.controller.user.vo.profile.SysUserProfileUpdateReqVO;
import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserCreateReqVO;
import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserExportReqVO;
import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserImportExcelVO;
import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserImportRespVO;
import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserPageReqVO;
import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserUpdateReqVO;
import cn.iocoder.dashboard.modules.system.controller.user.vo.user.*;
import cn.iocoder.dashboard.modules.system.convert.user.SysUserConvert;
import cn.iocoder.dashboard.modules.system.dal.dataobject.dept.SysDeptDO;
import cn.iocoder.dashboard.modules.system.dal.dataobject.dept.SysPostDO;
@ -26,21 +20,18 @@ import cn.iocoder.dashboard.modules.system.service.dept.SysDeptService;
import cn.iocoder.dashboard.modules.system.service.dept.SysPostService;
import cn.iocoder.dashboard.modules.system.service.permission.SysPermissionService;
import cn.iocoder.dashboard.util.collection.CollectionUtils;
import com.google.common.annotations.VisibleForTesting;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.*;
import static cn.iocoder.dashboard.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.dashboard.modules.system.enums.SysErrorCodeConstants.*;
@ -53,6 +44,9 @@ import static cn.iocoder.dashboard.modules.system.enums.SysErrorCodeConstants.*;
@Slf4j
public class SysUserServiceImpl implements SysUserService {
@Value("${sys.user.init-password:yudaoyuanma}")
private String userInitPassword;
@Resource
private SysUserMapper userMapper;
@ -142,8 +136,6 @@ public class SysUserServiceImpl implements SysUserService {
updateObj.setId(id);
updateObj.setStatus(status);
userMapper.updateById(updateObj);
// 删除用户关联数据
permissionService.processUserDeleted(id);
}
@Override
@ -152,6 +144,8 @@ public class SysUserServiceImpl implements SysUserService {
this.checkUserExists(id);
// 删除用户
userMapper.deleteById(id);
// 删除用户关联数据
permissionService.processUserDeleted(id);
}
@Override
@ -221,17 +215,19 @@ public class SysUserServiceImpl implements SysUserService {
this.checkPostEnable(postIds);
}
private void checkUserExists(Long id) {
@VisibleForTesting
void checkUserExists(Long id) {
if (id == null) {
return;
}
SysUserDO user = userMapper.selectById(id);
if (user == null) {
throw ServiceExceptionUtil.exception(USER_NOT_EXISTS);
throw exception(USER_NOT_EXISTS);
}
}
private void checkUsernameUnique(Long id, String username) {
@VisibleForTesting
void checkUsernameUnique(Long id, String username) {
if (StrUtil.isBlank(username)) {
return;
}
@ -241,14 +237,15 @@ public class SysUserServiceImpl implements SysUserService {
}
// 如果 id 为空说明不用比较是否为相同 id 的用户
if (id == null) {
throw ServiceExceptionUtil.exception(USER_USERNAME_EXISTS);
throw exception(USER_USERNAME_EXISTS);
}
if (!user.getId().equals(id)) {
throw ServiceExceptionUtil.exception(USER_USERNAME_EXISTS);
throw exception(USER_USERNAME_EXISTS);
}
}
private void checkEmailUnique(Long id, String email) {
@VisibleForTesting
void checkEmailUnique(Long id, String email) {
if (StrUtil.isBlank(email)) {
return;
}
@ -258,14 +255,15 @@ public class SysUserServiceImpl implements SysUserService {
}
// 如果 id 为空说明不用比较是否为相同 id 的用户
if (id == null) {
throw ServiceExceptionUtil.exception(USER_EMAIL_EXISTS);
throw exception(USER_EMAIL_EXISTS);
}
if (!user.getId().equals(id)) {
throw ServiceExceptionUtil.exception(USER_EMAIL_EXISTS);
throw exception(USER_EMAIL_EXISTS);
}
}
private void checkMobileUnique(Long id, String mobile) {
@VisibleForTesting
void checkMobileUnique(Long id, String mobile) {
if (StrUtil.isBlank(mobile)) {
return;
}
@ -275,42 +273,44 @@ public class SysUserServiceImpl implements SysUserService {
}
// 如果 id 为空说明不用比较是否为相同 id 的用户
if (id == null) {
throw ServiceExceptionUtil.exception(USER_MOBILE_EXISTS);
throw exception(USER_MOBILE_EXISTS);
}
if (!user.getId().equals(id)) {
throw ServiceExceptionUtil.exception(USER_MOBILE_EXISTS);
throw exception(USER_MOBILE_EXISTS);
}
}
private void checkDeptEnable(Long deptId) {
@VisibleForTesting
void checkDeptEnable(Long deptId) {
if (deptId == null) { // 允许不选择
return;
}
SysDeptDO dept = deptService.getDept(deptId);
if (dept == null) {
throw ServiceExceptionUtil.exception(DEPT_NOT_FOUND);
throw exception(DEPT_NOT_FOUND);
}
if (!CommonStatusEnum.ENABLE.getStatus().equals(dept.getStatus())) {
throw ServiceExceptionUtil.exception(DEPT_NOT_ENABLE);
throw exception(DEPT_NOT_ENABLE);
}
}
private void checkPostEnable(Set<Long> postIds) {
@VisibleForTesting
void checkPostEnable(Set<Long> postIds) {
if (CollUtil.isEmpty(postIds)) { // 允许不选择
return;
}
List<SysPostDO> posts = postService.getPosts(postIds, null);
if (CollUtil.isEmpty(posts)) {
throw ServiceExceptionUtil.exception(POST_NOT_FOUND);
throw exception(POST_NOT_FOUND);
}
Map<Long, SysPostDO> postMap = CollectionUtils.convertMap(posts, SysPostDO::getId);
postIds.forEach(postId -> {
SysPostDO post = postMap.get(postId);
if (post == null) {
throw ServiceExceptionUtil.exception(POST_NOT_FOUND);
throw exception(POST_NOT_FOUND);
}
if (!CommonStatusEnum.ENABLE.getStatus().equals(post.getStatus())) {
throw ServiceExceptionUtil.exception(POST_NOT_ENABLE, post.getName());
throw exception(POST_NOT_ENABLE, post.getName());
}
});
}
@ -321,13 +321,14 @@ public class SysUserServiceImpl implements SysUserService {
* @param id 用户 id
* @param oldPassword 旧密码
*/
private void checkOldPassword(Long id, String oldPassword) {
@VisibleForTesting
void checkOldPassword(Long id, String oldPassword) {
SysUserDO user = userMapper.selectById(id);
if (user == null) {
throw ServiceExceptionUtil.exception(USER_NOT_EXISTS);
throw exception(USER_NOT_EXISTS);
}
if (!passwordEncoder.matches(oldPassword, user.getPassword())) {
throw ServiceExceptionUtil.exception(USER_PASSWORD_FAILED);
throw exception(USER_PASSWORD_FAILED);
}
}
@ -335,7 +336,7 @@ public class SysUserServiceImpl implements SysUserService {
@Transactional(rollbackFor = Exception.class) // 添加事务异常则回滚所有导入
public SysUserImportRespVO importUsers(List<SysUserImportExcelVO> importUsers, boolean isUpdateSupport) {
if (CollUtil.isEmpty(importUsers)) {
throw ServiceExceptionUtil.exception(USER_IMPORT_LIST_IS_EMPTY);
throw exception(USER_IMPORT_LIST_IS_EMPTY);
}
SysUserImportRespVO respVO = SysUserImportRespVO.builder().createUsernames(new ArrayList<>())
.updateUsernames(new ArrayList<>()).failureUsernames(new LinkedHashMap<>()).build();
@ -351,8 +352,8 @@ public class SysUserServiceImpl implements SysUserService {
// 判断如果不存在在进行插入
SysUserDO existUser = userMapper.selectByUsername(importUser.getUsername());
if (existUser == null) {
// TODO 芋艿初始密码
userMapper.insert(SysUserConvert.INSTANCE.convert(importUser));
userMapper.insert(SysUserConvert.INSTANCE.convert(importUser)
.setPassword(passwordEncoder.encode(userInitPassword))); // 设置默认密码
respVO.getCreateUsernames().add(importUser.getUsername());
return;
}

View File

@ -1,7 +1,6 @@
package cn.iocoder.dashboard.modules.system.service.auth;
import static cn.hutool.core.util.RandomUtil.randomEle;
import static cn.iocoder.dashboard.modules.system.dal.redis.SysRedisKeyConstants.LOGIN_USER;
import static cn.iocoder.dashboard.util.AssertUtils.assertPojoEquals;
import static cn.iocoder.dashboard.util.RandomUtils.randomDate;
import static cn.iocoder.dashboard.util.RandomUtils.randomLongId;
@ -25,7 +24,6 @@ import javax.annotation.Resource;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.context.annotation.Import;
import org.springframework.data.redis.core.StringRedisTemplate;
import cn.hutool.core.date.DateUtil;
import cn.iocoder.dashboard.BaseDbAndRedisUnitTest;
@ -33,10 +31,6 @@ import cn.iocoder.dashboard.common.enums.CommonStatusEnum;
import cn.iocoder.dashboard.common.pojo.PageResult;
import cn.iocoder.dashboard.framework.security.config.SecurityProperties;
import cn.iocoder.dashboard.framework.security.core.LoginUser;
import cn.iocoder.dashboard.modules.infra.controller.job.vo.job.InfJobPageReqVO;
import cn.iocoder.dashboard.modules.infra.dal.dataobject.job.InfJobDO;
import cn.iocoder.dashboard.modules.infra.enums.config.InfConfigTypeEnum;
import cn.iocoder.dashboard.modules.infra.enums.job.InfJobStatusEnum;
import cn.iocoder.dashboard.modules.system.controller.auth.vo.session.SysUserSessionPageReqVO;
import cn.iocoder.dashboard.modules.system.dal.dataobject.auth.SysUserSessionDO;
import cn.iocoder.dashboard.modules.system.dal.dataobject.user.SysUserDO;
@ -50,7 +44,6 @@ import cn.iocoder.dashboard.modules.system.service.logger.impl.SysLoginLogServic
import cn.iocoder.dashboard.modules.system.service.user.SysUserServiceImpl;
import cn.iocoder.dashboard.util.AssertUtils;
import cn.iocoder.dashboard.util.RandomUtils;
import cn.iocoder.dashboard.util.json.JsonUtils;
import cn.iocoder.dashboard.util.object.ObjectUtils;
/**
@ -167,12 +160,12 @@ public class SysUserSessionServiceImplTest extends BaseDbAndRedisUnitTest {
String userIp = randomString();
SysUserDO dbUser1 = randomPojo(SysUserDO.class, o -> {
o.setUsername("testUsername1");
o.setSex(randomEle(SysSexEnum.values()).getSEX());
o.setSex(randomEle(SysSexEnum.values()).getSex());
o.setStatus(CommonStatusEnum.ENABLE.getStatus());
});
SysUserDO dbUser2 = randomPojo(SysUserDO.class, o -> {
o.setUsername("testUsername2");
o.setSex(randomEle(SysSexEnum.values()).getSEX());
o.setSex(randomEle(SysSexEnum.values()).getSex());
o.setStatus(CommonStatusEnum.ENABLE.getStatus());
});
SysUserSessionDO dbSession = randomPojo(SysUserSessionDO.class, o -> {

View File

@ -68,7 +68,7 @@ public class SysOperateLogServiceImplTest extends BaseDbUnitTest {
// 先构造用户
SysUserDO user = RandomUtils.randomPojo(SysUserDO.class, o -> {
o.setNickname("wangkai");
o.setSex(SysSexEnum.MALE.getSEX());
o.setSex(SysSexEnum.MALE.getSex());
o.setStatus(CommonStatusEnum.ENABLE.getStatus());
});
when(userService.getUsersByNickname("wangkai")).thenReturn(Collections.singletonList(user));
@ -119,7 +119,7 @@ public class SysOperateLogServiceImplTest extends BaseDbUnitTest {
// 先构造用户
SysUserDO user = RandomUtils.randomPojo(SysUserDO.class, o -> {
o.setNickname("wangkai");
o.setSex(SysSexEnum.MALE.getSEX());
o.setSex(SysSexEnum.MALE.getSex());
o.setStatus(CommonStatusEnum.ENABLE.getStatus());
});
when(userService.getUsersByNickname("wangkai")).thenReturn(Collections.singletonList(user));

View File

@ -56,7 +56,7 @@ public class SysSmsChannelServiceTest extends BaseDbUnitTest {
@Test
public void testInitLocalCache_success() {
// mock 数据s
// mock 数据
SysSmsChannelDO smsChannelDO01 = randomSmsChannelDO();
smsChannelMapper.insert(smsChannelDO01);
SysSmsChannelDO smsChannelDO02 = randomSmsChannelDO();

View File

@ -0,0 +1,590 @@
package cn.iocoder.dashboard.modules.system.service.user;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.RandomUtil;
import cn.iocoder.dashboard.BaseDbUnitTest;
import cn.iocoder.dashboard.common.enums.CommonStatusEnum;
import cn.iocoder.dashboard.common.pojo.PageResult;
import cn.iocoder.dashboard.modules.infra.service.file.InfFileService;
import cn.iocoder.dashboard.modules.system.controller.user.vo.profile.SysUserProfileUpdatePasswordReqVO;
import cn.iocoder.dashboard.modules.system.controller.user.vo.profile.SysUserProfileUpdateReqVO;
import cn.iocoder.dashboard.modules.system.controller.user.vo.user.*;
import cn.iocoder.dashboard.modules.system.dal.dataobject.dept.SysDeptDO;
import cn.iocoder.dashboard.modules.system.dal.dataobject.dept.SysPostDO;
import cn.iocoder.dashboard.modules.system.dal.dataobject.user.SysUserDO;
import cn.iocoder.dashboard.modules.system.dal.mysql.user.SysUserMapper;
import cn.iocoder.dashboard.modules.system.enums.common.SysSexEnum;
import cn.iocoder.dashboard.modules.system.service.dept.SysDeptService;
import cn.iocoder.dashboard.modules.system.service.dept.SysPostService;
import cn.iocoder.dashboard.modules.system.service.permission.SysPermissionService;
import cn.iocoder.dashboard.util.collection.ArrayUtils;
import cn.iocoder.dashboard.util.collection.CollectionUtils;
import cn.iocoder.dashboard.util.object.ObjectUtils;
import org.junit.jupiter.api.Test;
import org.mockito.stubbing.Answer;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.context.annotation.Import;
import org.springframework.security.crypto.password.PasswordEncoder;
import javax.annotation.Resource;
import java.io.ByteArrayInputStream;
import java.util.List;
import java.util.Set;
import java.util.function.Consumer;
import static cn.hutool.core.util.RandomUtil.randomBytes;
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 cn.iocoder.dashboard.util.date.DateUtils.buildTime;
import static org.assertj.core.util.Lists.newArrayList;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.mockito.ArgumentMatchers.*;
import static org.mockito.Mockito.*;
/**
* {@link SysUserService} 的单元测试类
*
* @author zxl
*/
@Import(SysUserServiceImpl.class)
public class SysUserServiceImplTest extends BaseDbUnitTest {
@Resource
private SysUserServiceImpl userService;
@Resource
private SysUserMapper userMapper;
@MockBean
private SysDeptService deptService;
@MockBean
private SysPostService postService;
@MockBean
private SysPermissionService permissionService;
@MockBean
private PasswordEncoder passwordEncoder;
@MockBean
private InfFileService fileService;
@Test
public void testCreatUser_success() {
// 准备参数
SysUserCreateReqVO reqVO = randomPojo(SysUserCreateReqVO.class, o -> {
o.setSex(RandomUtil.randomEle(SysSexEnum.values()).getSex());
o.setMobile(randomString());
});
// mock deptService 的方法
SysDeptDO dept = randomPojo(SysDeptDO.class, o -> {
o.setId(reqVO.getDeptId());
o.setStatus(CommonStatusEnum.ENABLE.getStatus());
});
when(deptService.getDept(eq(dept.getId()))).thenReturn(dept);
// mock postService 的方法
List<SysPostDO> posts = CollectionUtils.convertList(reqVO.getPostIds(), postId ->
randomPojo(SysPostDO.class, o -> {
o.setId(postId);
o.setStatus(CommonStatusEnum.ENABLE.getStatus());
}));
when(postService.getPosts(eq(reqVO.getPostIds()), isNull())).thenReturn(posts);
// mock passwordEncoder 的方法
when(passwordEncoder.encode(eq(reqVO.getPassword()))).thenReturn("yudaoyuanma");
// 调用
Long userId = userService.createUser(reqVO);
// 断言
SysUserDO user = userMapper.selectById(userId);
assertPojoEquals(reqVO, user, "password");
assertEquals("yudaoyuanma", user.getPassword());
assertEquals(CommonStatusEnum.ENABLE.getStatus(), user.getStatus());
}
@Test
public void testUpdateUser_success() {
// mock 数据
SysUserDO dbUser = randomSysUserDO();
userMapper.insert(dbUser);
// 准备参数
SysUserUpdateReqVO reqVO = randomPojo(SysUserUpdateReqVO.class, o -> {
o.setId(dbUser.getId());
o.setSex(RandomUtil.randomEle(SysSexEnum.values()).getSex());
o.setMobile(randomString());
});
// mock deptService 的方法
SysDeptDO dept = randomPojo(SysDeptDO.class, o -> {
o.setId(reqVO.getDeptId());
o.setStatus(CommonStatusEnum.ENABLE.getStatus());
});
when(deptService.getDept(eq(dept.getId()))).thenReturn(dept);
// mock postService 的方法
List<SysPostDO> posts = CollectionUtils.convertList(reqVO.getPostIds(), postId ->
randomPojo(SysPostDO.class, o -> {
o.setId(postId);
o.setStatus(CommonStatusEnum.ENABLE.getStatus());
}));
when(postService.getPosts(eq(reqVO.getPostIds()), isNull())).thenReturn(posts);
// 调用
userService.updateUser(reqVO);
// 断言
SysUserDO user = userMapper.selectById(reqVO.getId());
assertPojoEquals(reqVO, user);
}
@Test
public void testUpdateUserProfile_success() {
// mock 数据
SysUserDO dbUser = randomSysUserDO();
userMapper.insert(dbUser);
// 准备参数
Long userId = dbUser.getId();
SysUserProfileUpdateReqVO reqVO = randomPojo(SysUserProfileUpdateReqVO.class, o -> {
o.setMobile(randomString());
o.setSex(RandomUtil.randomEle(SysSexEnum.values()).getSex());
});
// 调用
userService.updateUserProfile(userId, reqVO);
// 断言
SysUserDO user = userMapper.selectById(userId);
assertPojoEquals(reqVO, user);
}
@Test
public void testUpdateUserPassword_success() {
// mock 数据
SysUserDO dbUser = randomSysUserDO(o -> o.setPassword("encode:yudao"));
userMapper.insert(dbUser);
// 准备参数
Long userId = dbUser.getId();
SysUserProfileUpdatePasswordReqVO reqVO = randomPojo(SysUserProfileUpdatePasswordReqVO.class, o -> {
o.setOldPassword("yudao");
o.setNewPassword("yuanma");
});
// mock 方法
when(passwordEncoder.encode(anyString())).then(
(Answer<String>) invocationOnMock -> "encode:" + invocationOnMock.getArgument(0));
when(passwordEncoder.matches(eq(reqVO.getOldPassword()), eq(dbUser.getPassword()))).thenReturn(true);
// 调用
userService.updateUserPassword(userId, reqVO);
// 断言
SysUserDO user = userMapper.selectById(userId);
assertEquals("encode:yuanma", user.getPassword());
}
@Test
public void testUpdateUserAvatar_success() {
// mock 数据
SysUserDO dbUser = randomSysUserDO();
userMapper.insert(dbUser);
// 准备参数
Long userId = dbUser.getId();
byte[] avatarFileBytes = randomBytes(10);
ByteArrayInputStream avatarFile = new ByteArrayInputStream(avatarFileBytes);
// mock 方法
String avatar = randomString();
when(fileService.createFile(anyString(), eq(avatarFileBytes))).thenReturn(avatar);
// 调用
userService.updateUserAvatar(userId, avatarFile);
// 断言
SysUserDO user = userMapper.selectById(userId);
assertEquals(avatar, user.getAvatar());
}
@Test
public void testUpdateUserPassword02_success() {
// mock 数据
SysUserDO dbUser = randomSysUserDO();
userMapper.insert(dbUser);
// 准备参数
Long userId = dbUser.getId();
String password = "yudao";
// mock 方法
when(passwordEncoder.encode(anyString())).then(
(Answer<String>) invocationOnMock -> "encode:" + invocationOnMock.getArgument(0));
// 调用
userService.updateUserPassword(userId, password);
// 断言
SysUserDO user = userMapper.selectById(userId);
assertEquals("encode:" + password, user.getPassword());
}
@Test
public void testUpdateUserStatus() {
// mock 数据
SysUserDO dbUser = randomSysUserDO();
userMapper.insert(dbUser);
// 准备参数
Long userId = dbUser.getId();
Integer status = randomCommonStatus();
// 调用
userService.updateUserStatus(userId, status);
// 断言
SysUserDO user = userMapper.selectById(userId);
assertEquals(status, user.getStatus());
}
@Test
public void testDeleteUser_success(){
// mock 数据
SysUserDO dbUser = randomSysUserDO();
userMapper.insert(dbUser);
// 准备参数
Long userId = dbUser.getId();
// 调用数据
userService.deleteUser(userId);
// 校验结果
assertNull(userService.getUser(userId));
// 校验调用次数
verify(permissionService, times(1)).processUserDeleted(eq(userId));
}
@Test
public void testGetUserPage() {
// mock 数据
SysUserDO dbUser = initGetUserPageData();
// 准备参数
SysUserPageReqVO reqVO = new SysUserPageReqVO();
reqVO.setUsername("yudao");
reqVO.setMobile("1560");
reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus());
reqVO.setBeginTime(buildTime(2020, 12, 1));
reqVO.setEndTime(buildTime(2020, 12, 24));
reqVO.setDeptId(1L); // 其中1L 2L 的父部门
// mock 方法
List<SysDeptDO> deptList = newArrayList(randomPojo(SysDeptDO.class, o -> o.setId(2L)));
when(deptService.getDeptsByParentIdFromCache(eq(reqVO.getDeptId()), eq(true))).thenReturn(deptList);
// 调用
PageResult<SysUserDO> pageResult = userService.getUserPage(reqVO);
// 断言
assertEquals(1, pageResult.getTotal());
assertEquals(1, pageResult.getList().size());
assertPojoEquals(dbUser, pageResult.getList().get(0));
}
@Test
public void testGetUsers() {
// mock 数据
SysUserDO dbUser = initGetUserPageData();
// 准备参数
SysUserExportReqVO reqVO = new SysUserExportReqVO();
reqVO.setUsername("yudao");
reqVO.setMobile("1560");
reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus());
reqVO.setBeginTime(buildTime(2020, 12, 1));
reqVO.setEndTime(buildTime(2020, 12, 24));
reqVO.setDeptId(1L); // 其中1L 2L 的父部门
// mock 方法
List<SysDeptDO> deptList = newArrayList(randomPojo(SysDeptDO.class, o -> o.setId(2L)));
when(deptService.getDeptsByParentIdFromCache(eq(reqVO.getDeptId()), eq(true))).thenReturn(deptList);
// 调用
List<SysUserDO> list = userService.getUsers(reqVO);
// 断言
assertEquals(1, list.size());
assertPojoEquals(dbUser, list.get(0));
}
/**
* 初始化 getUserPage 方法的测试数据
*/
private SysUserDO initGetUserPageData() {
// mock 数据
SysUserDO dbUser = randomSysUserDO(o -> { // 等会查询到
o.setUsername("yudaoyuanma");
o.setMobile("15601691300");
o.setStatus(CommonStatusEnum.ENABLE.getStatus());
o.setCreateTime(buildTime(2020, 12, 12));
o.setDeptId(2L);
});
userMapper.insert(dbUser);
// 测试 username 不匹配
userMapper.insert(ObjectUtils.clone(dbUser, o -> o.setUsername("yuanma")));
// 测试 mobile 不匹配
userMapper.insert(ObjectUtils.clone(dbUser, o -> o.setMobile("18818260888")));
// 测试 status 不匹配
userMapper.insert(ObjectUtils.clone(dbUser, o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus())));
// 测试 createTime 不匹配
userMapper.insert(ObjectUtils.clone(dbUser, o -> o.setCreateTime(buildTime(2020, 11, 11))));
// 测试 dept 不匹配
userMapper.insert(ObjectUtils.clone(dbUser, o -> o.setDeptId(0L)));
return dbUser;
}
/**
* 情况一校验不通过导致插入失败
*/
@Test
public void testImportUsers_01() {
// 准备参数
SysUserImportExcelVO importUser = randomPojo(SysUserImportExcelVO.class);
// mock 方法
// 调用
SysUserImportRespVO respVO = userService.importUsers(newArrayList(importUser), true);
// 断言
assertEquals(0, respVO.getCreateUsernames().size());
assertEquals(0, respVO.getUpdateUsernames().size());
assertEquals(1, respVO.getFailureUsernames().size());
assertEquals(DEPT_NOT_FOUND.getMsg(), respVO.getFailureUsernames().get(importUser.getUsername()));
}
/**
* 情况二不存在进行插入
*/
@Test
public void testImportUsers_02() {
// 准备参数
SysUserImportExcelVO importUser = randomPojo(SysUserImportExcelVO.class, o -> {
o.setStatus(randomEle(CommonStatusEnum.values()).getStatus()); // 保证 status 的范围
o.setSex(randomEle(SysSexEnum.values()).getSex()); // 保证 sex 的范围
});
// mock deptService 的方法
SysDeptDO dept = randomPojo(SysDeptDO.class, o -> {
o.setId(importUser.getDeptId());
o.setStatus(CommonStatusEnum.ENABLE.getStatus());
});
when(deptService.getDept(eq(dept.getId()))).thenReturn(dept);
// mock passwordEncoder 的方法
when(passwordEncoder.encode(eq("yudaoyuanma"))).thenReturn("java");
// 调用
SysUserImportRespVO respVO = userService.importUsers(newArrayList(importUser), true);
// 断言
assertEquals(1, respVO.getCreateUsernames().size());
SysUserDO user = userMapper.selectByUsername(respVO.getCreateUsernames().get(0));
assertPojoEquals(importUser, user);
assertEquals("java", user.getPassword());
assertEquals(0, respVO.getUpdateUsernames().size());
assertEquals(0, respVO.getFailureUsernames().size());
}
/**
* 情况三存在但是不强制更新
*/
@Test
public void testImportUsers_03() {
// mock 数据
SysUserDO dbUser = randomSysUserDO();
userMapper.insert(dbUser);
// 准备参数
SysUserImportExcelVO importUser = randomPojo(SysUserImportExcelVO.class, o -> {
o.setStatus(randomEle(CommonStatusEnum.values()).getStatus()); // 保证 status 的范围
o.setSex(randomEle(SysSexEnum.values()).getSex()); // 保证 sex 的范围
o.setUsername(dbUser.getUsername());
});
// mock deptService 的方法
SysDeptDO dept = randomPojo(SysDeptDO.class, o -> {
o.setId(importUser.getDeptId());
o.setStatus(CommonStatusEnum.ENABLE.getStatus());
});
when(deptService.getDept(eq(dept.getId()))).thenReturn(dept);
// 调用
SysUserImportRespVO respVO = userService.importUsers(newArrayList(importUser), false);
// 断言
assertEquals(0, respVO.getCreateUsernames().size());
assertEquals(0, respVO.getUpdateUsernames().size());
assertEquals(1, respVO.getFailureUsernames().size());
assertEquals(USER_USERNAME_EXISTS.getMsg(), respVO.getFailureUsernames().get(importUser.getUsername()));
}
/**
* 情况四存在强制更新
*/
@Test
public void testImportUsers_04() {
// mock 数据
SysUserDO dbUser = randomSysUserDO();
userMapper.insert(dbUser);
// 准备参数
SysUserImportExcelVO importUser = randomPojo(SysUserImportExcelVO.class, o -> {
o.setStatus(randomEle(CommonStatusEnum.values()).getStatus()); // 保证 status 的范围
o.setSex(randomEle(SysSexEnum.values()).getSex()); // 保证 sex 的范围
o.setUsername(dbUser.getUsername());
});
// mock deptService 的方法
SysDeptDO dept = randomPojo(SysDeptDO.class, o -> {
o.setId(importUser.getDeptId());
o.setStatus(CommonStatusEnum.ENABLE.getStatus());
});
when(deptService.getDept(eq(dept.getId()))).thenReturn(dept);
// 调用
SysUserImportRespVO respVO = userService.importUsers(newArrayList(importUser), true);
// 断言
assertEquals(0, respVO.getCreateUsernames().size());
assertEquals(1, respVO.getUpdateUsernames().size());
SysUserDO user = userMapper.selectByUsername(respVO.getUpdateUsernames().get(0));
assertPojoEquals(importUser, user);
assertEquals(0, respVO.getFailureUsernames().size());
}
@Test
public void testCheckUserExists_notExists() {
assertServiceException(() -> userService.checkUserExists(randomLongId()), USER_NOT_EXISTS);
}
@Test
public void testCheckUsernameUnique_usernameExistsForCreate() {
// 准备参数
String username = randomString();
// mock 数据
userMapper.insert(randomSysUserDO(o -> o.setUsername(username)));
// 调用校验异常
assertServiceException(() -> userService.checkUsernameUnique(null, username),
USER_USERNAME_EXISTS);
}
@Test
public void testCheckUsernameUnique_usernameExistsForUpdate() {
// 准备参数
Long id = randomLongId();
String username = randomString();
// mock 数据
userMapper.insert(randomSysUserDO(o -> o.setUsername(username)));
// 调用校验异常
assertServiceException(() -> userService.checkUsernameUnique(id, username),
USER_USERNAME_EXISTS);
}
@Test
public void testCheckEmailUnique_emailExistsForCreate() {
// 准备参数
String email = randomString();
// mock 数据
userMapper.insert(randomSysUserDO(o -> o.setEmail(email)));
// 调用校验异常
assertServiceException(() -> userService.checkEmailUnique(null, email),
USER_EMAIL_EXISTS);
}
@Test
public void testCheckEmailUnique_emailExistsForUpdate() {
// 准备参数
Long id = randomLongId();
String email = randomString();
// mock 数据
userMapper.insert(randomSysUserDO(o -> o.setEmail(email)));
// 调用校验异常
assertServiceException(() -> userService.checkEmailUnique(id, email),
USER_EMAIL_EXISTS);
}
@Test
public void testCheckMobileUnique_mobileExistsForCreate() {
// 准备参数
String mobile = randomString();
// mock 数据
userMapper.insert(randomSysUserDO(o -> o.setMobile(mobile)));
// 调用校验异常
assertServiceException(() -> userService.checkMobileUnique(null, mobile),
USER_MOBILE_EXISTS);
}
@Test
public void testCheckMobileUnique_mobileExistsForUpdate() {
// 准备参数
Long id = randomLongId();
String mobile = randomString();
// mock 数据
userMapper.insert(randomSysUserDO(o -> o.setMobile(mobile)));
// 调用校验异常
assertServiceException(() -> userService.checkMobileUnique(id, mobile),
USER_MOBILE_EXISTS);
}
@Test
public void testCheckDeptEnable_notFound() {
assertServiceException(() -> userService.checkDeptEnable(randomLongId()),
DEPT_NOT_FOUND);
}
@Test
public void testCheckDeptEnable_notEnable() {
// 准备参数
Long deptId = randomLongId();
// mock deptService 的方法
SysDeptDO dept = randomPojo(SysDeptDO.class, o -> {
o.setId(deptId);
o.setStatus(CommonStatusEnum.DISABLE.getStatus());
});
when(deptService.getDept(eq(dept.getId()))).thenReturn(dept);
// 调用校验异常
assertServiceException(() -> userService.checkDeptEnable(deptId),
DEPT_NOT_ENABLE);
}
@Test
public void testCheckPostEnable_notFound() {
assertServiceException(() -> userService.checkPostEnable(randomSet(Long.class)),
POST_NOT_FOUND);
}
@Test
public void testCheckPostEnable_notEnable() {
// 准备参数
Set<Long> postIds = randomSet(Long.class);
// mock postService 的方法
List<SysPostDO> posts = CollectionUtils.convertList(postIds, postId ->
randomPojo(SysPostDO.class, o -> {
o.setId(postId);
o.setStatus(CommonStatusEnum.DISABLE.getStatus());
}));
when(postService.getPosts(eq(postIds), isNull())).thenReturn(posts);
// 调用校验异常
assertServiceException(() -> userService.checkPostEnable(postIds),
POST_NOT_ENABLE, CollUtil.getFirst(posts).getName());
}
@Test
public void testCheckOldPassword_notExists() {
assertServiceException(() -> userService.checkOldPassword(randomLongId(), randomString()),
USER_NOT_EXISTS);
}
@Test
public void testCheckOldPassword_passwordFailed() {
// mock 数据
SysUserDO user = randomSysUserDO();
userMapper.insert(user);
// 准备参数
Long id = user.getId();
String oldPassword = user.getPassword();
// 调用校验异常
assertServiceException(() -> userService.checkOldPassword(id, oldPassword),
USER_PASSWORD_FAILED);
// 校验调用
verify(passwordEncoder, times(1)).matches(eq(oldPassword), eq(user.getPassword()));
}
// ========== 随机对象 ==========
@SafeVarargs
private static SysUserDO randomSysUserDO(Consumer<SysUserDO>... consumers) {
Consumer<SysUserDO> consumer = (o) -> {
o.setStatus(randomEle(CommonStatusEnum.values()).getStatus()); // 保证 status 的范围
o.setSex(randomEle(SysSexEnum.values()).getSex()); // 保证 sex 的范围
};
return randomPojo(SysUserDO.class, ArrayUtils.append(consumer, consumers));
}
}