Commit 632be011b360142fc790bf8d6abc27045ce7ef10

Authored by YunaiV
1 parent 92997a0c

增加 podam 随机生成对象,简化单元测试的成本

@@ -190,6 +190,13 @@ @@ -190,6 +190,13 @@
190 <scope>test</scope> 190 <scope>test</scope>
191 </dependency> 191 </dependency>
192 192
  193 + <dependency>
  194 + <groupId>uk.co.jemos.podam</groupId> <!-- 单元测试,随机生成 POJO 类 -->
  195 + <artifactId>podam</artifactId>
  196 + <version>7.2.6.RELEASE</version>
  197 + <scope>test</scope>
  198 + </dependency>
  199 +
193 <!-- 工具类相关 --> 200 <!-- 工具类相关 -->
194 <dependency> 201 <dependency>
195 <groupId>org.projectlombok</groupId> 202 <groupId>org.projectlombok</groupId>
src/main/java/cn/iocoder/dashboard/framework/apollo/internals/DBConfigRepository.java
@@ -122,7 +122,7 @@ public class DBConfigRepository extends AbstractConfigRepository { @@ -122,7 +122,7 @@ public class DBConfigRepository extends AbstractConfigRepository {
122 122
123 private Properties buildProperties(List<InfConfigDO> configs) { 123 private Properties buildProperties(List<InfConfigDO> configs) {
124 Properties properties = propertiesFactory.getPropertiesInstance(); 124 Properties properties = propertiesFactory.getPropertiesInstance();
125 - configs.stream().filter(config -> 0 == config.getDeleted()) // 过滤掉被删除的配置 125 + configs.stream().filter(BaseDO::getDeleted) // 过滤掉被删除的配置
126 .forEach(config -> properties.put(config.getKey(), config.getValue())); 126 .forEach(config -> properties.put(config.getKey(), config.getValue()));
127 return properties; 127 return properties;
128 } 128 }
src/main/java/cn/iocoder/dashboard/framework/mybatis/core/dataobject/BaseDO.java
@@ -32,6 +32,6 @@ public class BaseDO implements Serializable { @@ -32,6 +32,6 @@ public class BaseDO implements Serializable {
32 * 是否删除 32 * 是否删除
33 */ 33 */
34 @TableLogic 34 @TableLogic
35 - private Integer deleted; 35 + private Boolean deleted;
36 36
37 } 37 }
src/main/java/cn/iocoder/dashboard/modules/system/service/auth/impl/SysAuthServiceImpl.java
@@ -85,7 +85,7 @@ public class SysAuthServiceImpl implements SysAuthService { @@ -85,7 +85,7 @@ public class SysAuthServiceImpl implements SysAuthService {
85 @Override 85 @Override
86 public String login(SysAuthLoginReqVO reqVO, String userIp, String userAgent) { 86 public String login(SysAuthLoginReqVO reqVO, String userIp, String userAgent) {
87 // 判断验证码是否正确 87 // 判断验证码是否正确
88 -// this.verifyCaptcha(reqVO.getUsername(), reqVO.getUuid(), reqVO.getCode()); 88 + this.verifyCaptcha(reqVO.getUsername(), reqVO.getUuid(), reqVO.getCode());
89 89
90 // 使用账号密码,进行登陆。 90 // 使用账号密码,进行登陆。
91 LoginUser loginUser = this.login0(reqVO.getUsername(), reqVO.getPassword()); 91 LoginUser loginUser = this.login0(reqVO.getUsername(), reqVO.getPassword());
@@ -99,11 +99,13 @@ public class SysAuthServiceImpl implements SysAuthService { @@ -99,11 +99,13 @@ public class SysAuthServiceImpl implements SysAuthService {
99 String code = captchaService.getCaptchaCode(captchaUUID); 99 String code = captchaService.getCaptchaCode(captchaUUID);
100 // 验证码不存在 100 // 验证码不存在
101 if (code == null) { 101 if (code == null) {
  102 + // 创建登陆失败日志(验证码不存在)
102 this.createLoginLog(username, SysLoginResultEnum.CAPTCHA_NOT_FOUND); 103 this.createLoginLog(username, SysLoginResultEnum.CAPTCHA_NOT_FOUND);
103 throw ServiceExceptionUtil.exception(AUTH_LOGIN_CAPTCHA_NOT_FOUND); 104 throw ServiceExceptionUtil.exception(AUTH_LOGIN_CAPTCHA_NOT_FOUND);
104 } 105 }
105 // 验证码不正确 106 // 验证码不正确
106 if (!code.equals(captchaCode)) { 107 if (!code.equals(captchaCode)) {
  108 + // 创建登陆失败日志(验证码不正确)
107 this.createLoginLog(username, SysLoginResultEnum.CAPTCHA_CODE_ERROR); 109 this.createLoginLog(username, SysLoginResultEnum.CAPTCHA_CODE_ERROR);
108 throw ServiceExceptionUtil.exception(AUTH_LOGIN_CAPTCHA_CODE_ERROR); 110 throw ServiceExceptionUtil.exception(AUTH_LOGIN_CAPTCHA_CODE_ERROR);
109 } 111 }
src/test/java/cn/iocoder/dashboard/modules/system/service/auth/SysAuthServiceImplTest.java
1 package cn.iocoder.dashboard.modules.system.service.auth; 1 package cn.iocoder.dashboard.modules.system.service.auth;
2 2
3 import cn.iocoder.dashboard.BaseSpringBootUnitTest; 3 import cn.iocoder.dashboard.BaseSpringBootUnitTest;
  4 +import cn.iocoder.dashboard.framework.security.core.LoginUser;
4 import cn.iocoder.dashboard.modules.system.dal.dataobject.user.SysUserDO; 5 import cn.iocoder.dashboard.modules.system.dal.dataobject.user.SysUserDO;
5 import cn.iocoder.dashboard.modules.system.service.auth.impl.SysAuthServiceImpl; 6 import cn.iocoder.dashboard.modules.system.service.auth.impl.SysAuthServiceImpl;
6 import cn.iocoder.dashboard.modules.system.service.user.SysUserService; 7 import cn.iocoder.dashboard.modules.system.service.user.SysUserService;
  8 +import cn.iocoder.dashboard.util.AssertUtils;
7 import org.junit.jupiter.api.Test; 9 import org.junit.jupiter.api.Test;
8 import org.springframework.boot.test.mock.mockito.MockBean; 10 import org.springframework.boot.test.mock.mockito.MockBean;
9 11
10 import javax.annotation.Resource; 12 import javax.annotation.Resource;
11 13
12 -import static cn.iocoder.dashboard.util.RandomUtils.*; 14 +import static cn.iocoder.dashboard.util.RandomUtils.randomString;
  15 +import static cn.iocoder.dashboard.util.RandomUtils.randomUserDO;
  16 +import static org.junit.jupiter.api.Assertions.assertNull;
13 import static org.mockito.ArgumentMatchers.eq; 17 import static org.mockito.ArgumentMatchers.eq;
14 import static org.mockito.Mockito.when; 18 import static org.mockito.Mockito.when;
15 19
@@ -28,6 +32,12 @@ public class SysAuthServiceImplTest extends BaseSpringBootUnitTest { @@ -28,6 +32,12 @@ public class SysAuthServiceImplTest extends BaseSpringBootUnitTest {
28 // mock 方法 32 // mock 方法
29 SysUserDO user = randomUserDO(); 33 SysUserDO user = randomUserDO();
30 when(userService.getUserByUserName(eq(username))).thenReturn(user); 34 when(userService.getUserByUserName(eq(username))).thenReturn(user);
  35 +
  36 + // 调用
  37 + LoginUser loginUser = (LoginUser) authService.loadUserByUsername(username);
  38 + // 校验
  39 + AssertUtils.assertEquals(user, loginUser, "updateTime");
  40 + assertNull(loginUser.getRoleIds()); // 此时不会加载角色,所以是空的
31 } 41 }
32 42
33 } 43 }
src/test/java/cn/iocoder/dashboard/util/AssertUtils.java
1 package cn.iocoder.dashboard.util; 1 package cn.iocoder.dashboard.util;
2 2
  3 +import cn.hutool.core.util.ArrayUtil;
3 import cn.hutool.core.util.ReflectUtil; 4 import cn.hutool.core.util.ReflectUtil;
4 import cn.iocoder.dashboard.common.exception.ErrorCode; 5 import cn.iocoder.dashboard.common.exception.ErrorCode;
5 import cn.iocoder.dashboard.common.exception.ServiceException; 6 import cn.iocoder.dashboard.common.exception.ServiceException;
@@ -22,10 +23,15 @@ public class AssertUtils { @@ -22,10 +23,15 @@ public class AssertUtils {
22 * 23 *
23 * @param expected 期望对象 24 * @param expected 期望对象
24 * @param actual 实际对象 25 * @param actual 实际对象
  26 + * @param ignoreFields 忽略的属性数组
25 */ 27 */
26 - public static void assertEquals(Object expected, Object actual) { 28 + public static void assertEquals(Object expected, Object actual, String... ignoreFields) {
27 Field[] expectedFields = ReflectUtil.getFields(expected.getClass()); 29 Field[] expectedFields = ReflectUtil.getFields(expected.getClass());
28 Arrays.stream(expectedFields).forEach(expectedField -> { 30 Arrays.stream(expectedFields).forEach(expectedField -> {
  31 + // 如果是忽略的属性,则不进行比对
  32 + if (ArrayUtil.contains(ignoreFields, expectedField.getName())) {
  33 + return;
  34 + }
29 // 忽略不存在的属性 35 // 忽略不存在的属性
30 Field actualField = ReflectUtil.getField(actual.getClass(), expectedField.getName()); 36 Field actualField = ReflectUtil.getField(actual.getClass(), expectedField.getName());
31 if (actualField == null) { 37 if (actualField == null) {
src/test/java/cn/iocoder/dashboard/util/RandomUtils.java
1 package cn.iocoder.dashboard.util; 1 package cn.iocoder.dashboard.util;
2 2
3 -import cn.hutool.core.util.*; 3 +import cn.hutool.core.util.ArrayUtil;
  4 +import cn.hutool.core.util.RandomUtil;
4 import cn.iocoder.dashboard.modules.system.dal.dataobject.user.SysUserDO; 5 import cn.iocoder.dashboard.modules.system.dal.dataobject.user.SysUserDO;
  6 +import uk.co.jemos.podam.api.PodamFactory;
  7 +import uk.co.jemos.podam.api.PodamFactoryImpl;
5 8
6 -import java.lang.reflect.Field; 9 +import java.util.Arrays;
  10 +import java.util.Date;
  11 +import java.util.function.Consumer;
7 12
8 /** 13 /**
9 * 随机工具类 14 * 随机工具类
@@ -14,6 +19,10 @@ public class RandomUtils { @@ -14,6 +19,10 @@ public class RandomUtils {
14 19
15 private static final int RANDOM_STRING_LENGTH = 10; 20 private static final int RANDOM_STRING_LENGTH = 10;
16 21
  22 + private static final int RANDOM_DATE_MAX = 30;
  23 +
  24 + private static final PodamFactory PODAM_FACTORY = new PodamFactoryImpl();
  25 +
17 public static String randomString() { 26 public static String randomString() {
18 return RandomUtil.randomString(RANDOM_STRING_LENGTH); 27 return RandomUtil.randomString(RANDOM_STRING_LENGTH);
19 } 28 }
@@ -26,41 +35,27 @@ public class RandomUtils { @@ -26,41 +35,27 @@ public class RandomUtils {
26 return RandomUtil.randomInt(0, Integer.MAX_VALUE); 35 return RandomUtil.randomInt(0, Integer.MAX_VALUE);
27 } 36 }
28 37
  38 + public static Date randomDate() {
  39 + return RandomUtil.randomDay(0, RANDOM_DATE_MAX);
  40 + }
  41 +
29 public static Short randomShort() { 42 public static Short randomShort() {
30 return (short) RandomUtil.randomInt(0, Short.MAX_VALUE); 43 return (short) RandomUtil.randomInt(0, Short.MAX_VALUE);
31 } 44 }
32 45
33 - public static SysUserDO randomUserDO() {  
34 - SysUserDO user = randomObject(SysUserDO.class);  
35 - return user; 46 + @SafeVarargs
  47 + public static SysUserDO randomUserDO(Consumer<SysUserDO>... consumers) {
  48 + return randomPojo(SysUserDO.class, consumers);
36 } 49 }
37 50
38 - private static <T> T randomObject(Class<T> clazz) {  
39 - // 创建对象  
40 - T object = ReflectUtil.newInstance(clazz);  
41 - // 遍历属性,设置随机值  
42 - for (Field field : ReflectUtil.getFields(clazz)) {  
43 - // 数字类型  
44 - if (field.getType() == Long.class) {  
45 - ReflectUtil.setFieldValue(object, field, randomLong());  
46 - continue;  
47 - }  
48 - if (field.getType() == Integer.class) {  
49 - ReflectUtil.setFieldValue(object, field, randomInteger());  
50 - continue;  
51 - }  
52 - if (field.getType() == Short.class) {  
53 - ReflectUtil.setFieldValue(object, field, randomShort());  
54 - continue;  
55 - }  
56 - // 字符串类型  
57 - if (field.getType() == String.class) {  
58 - ReflectUtil.setFieldValue(object, field, randomString());  
59 - continue;  
60 - }  
61 -// System.out.println(); 51 + @SafeVarargs
  52 + private static <T> T randomPojo(Class<T> clazz, Consumer<T>... consumers) {
  53 + T pojo = PODAM_FACTORY.manufacturePojo(clazz);
  54 + // 非空时,回调逻辑。通过它,可以实现 Pojo 的进一步处理
  55 + if (ArrayUtil.isNotEmpty(consumers)) {
  56 + Arrays.stream(consumers).forEach(consumer -> consumer.accept(pojo));
62 } 57 }
63 - return object; 58 + return pojo;
64 } 59 }
65 60
66 } 61 }