Browse Source

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

YunaiV 4 years ago
parent
commit
632be011b3

+ 7 - 0
pom.xml

@@ -190,6 +190,13 @@
             <scope>test</scope>
         </dependency>
 
+        <dependency>
+            <groupId>uk.co.jemos.podam</groupId> <!-- 单元测试,随机生成 POJO 类 -->
+            <artifactId>podam</artifactId>
+            <version>7.2.6.RELEASE</version>
+            <scope>test</scope>
+        </dependency>
+
         <!-- 工具类相关 -->
         <dependency>
             <groupId>org.projectlombok</groupId>

+ 1 - 1
src/main/java/cn/iocoder/dashboard/framework/apollo/internals/DBConfigRepository.java

@@ -122,7 +122,7 @@ public class DBConfigRepository extends AbstractConfigRepository {
 
     private Properties buildProperties(List<InfConfigDO> configs) {
         Properties properties = propertiesFactory.getPropertiesInstance();
-        configs.stream().filter(config -> 0 == config.getDeleted()) // 过滤掉被删除的配置
+        configs.stream().filter(BaseDO::getDeleted) // 过滤掉被删除的配置
                 .forEach(config -> properties.put(config.getKey(), config.getValue()));
         return properties;
     }

+ 1 - 1
src/main/java/cn/iocoder/dashboard/framework/mybatis/core/dataobject/BaseDO.java

@@ -32,6 +32,6 @@ public class BaseDO implements Serializable {
      * 是否删除
      */
     @TableLogic
-    private Integer deleted;
+    private Boolean deleted;
 
 }

+ 3 - 1
src/main/java/cn/iocoder/dashboard/modules/system/service/auth/impl/SysAuthServiceImpl.java

@@ -85,7 +85,7 @@ public class SysAuthServiceImpl implements SysAuthService {
     @Override
     public String login(SysAuthLoginReqVO reqVO, String userIp, String userAgent) {
         // 判断验证码是否正确
-//        this.verifyCaptcha(reqVO.getUsername(), reqVO.getUuid(), reqVO.getCode());
+        this.verifyCaptcha(reqVO.getUsername(), reqVO.getUuid(), reqVO.getCode());
 
         // 使用账号密码,进行登陆。
         LoginUser loginUser = this.login0(reqVO.getUsername(), reqVO.getPassword());
@@ -99,11 +99,13 @@ public class SysAuthServiceImpl implements SysAuthService {
         String code = captchaService.getCaptchaCode(captchaUUID);
         // 验证码不存在
         if (code == null) {
+            // 创建登陆失败日志(验证码不存在)
             this.createLoginLog(username, SysLoginResultEnum.CAPTCHA_NOT_FOUND);
             throw ServiceExceptionUtil.exception(AUTH_LOGIN_CAPTCHA_NOT_FOUND);
         }
         // 验证码不正确
         if (!code.equals(captchaCode)) {
+            // 创建登陆失败日志(验证码不正确)
             this.createLoginLog(username, SysLoginResultEnum.CAPTCHA_CODE_ERROR);
             throw ServiceExceptionUtil.exception(AUTH_LOGIN_CAPTCHA_CODE_ERROR);
         }

+ 11 - 1
src/test/java/cn/iocoder/dashboard/modules/system/service/auth/SysAuthServiceImplTest.java

@@ -1,15 +1,19 @@
 package cn.iocoder.dashboard.modules.system.service.auth;
 
 import cn.iocoder.dashboard.BaseSpringBootUnitTest;
+import cn.iocoder.dashboard.framework.security.core.LoginUser;
 import cn.iocoder.dashboard.modules.system.dal.dataobject.user.SysUserDO;
 import cn.iocoder.dashboard.modules.system.service.auth.impl.SysAuthServiceImpl;
 import cn.iocoder.dashboard.modules.system.service.user.SysUserService;
+import cn.iocoder.dashboard.util.AssertUtils;
 import org.junit.jupiter.api.Test;
 import org.springframework.boot.test.mock.mockito.MockBean;
 
 import javax.annotation.Resource;
 
-import static cn.iocoder.dashboard.util.RandomUtils.*;
+import static cn.iocoder.dashboard.util.RandomUtils.randomString;
+import static cn.iocoder.dashboard.util.RandomUtils.randomUserDO;
+import static org.junit.jupiter.api.Assertions.assertNull;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.when;
 
@@ -28,6 +32,12 @@ public class SysAuthServiceImplTest extends BaseSpringBootUnitTest {
         // mock 方法
         SysUserDO user = randomUserDO();
         when(userService.getUserByUserName(eq(username))).thenReturn(user);
+
+        // 调用
+        LoginUser loginUser = (LoginUser) authService.loadUserByUsername(username);
+        // 校验
+        AssertUtils.assertEquals(user, loginUser, "updateTime");
+        assertNull(loginUser.getRoleIds()); // 此时不会加载角色,所以是空的
     }
 
 }

+ 7 - 1
src/test/java/cn/iocoder/dashboard/util/AssertUtils.java

@@ -1,5 +1,6 @@
 package cn.iocoder.dashboard.util;
 
+import cn.hutool.core.util.ArrayUtil;
 import cn.hutool.core.util.ReflectUtil;
 import cn.iocoder.dashboard.common.exception.ErrorCode;
 import cn.iocoder.dashboard.common.exception.ServiceException;
@@ -22,10 +23,15 @@ public class AssertUtils {
      *
      * @param expected 期望对象
      * @param actual 实际对象
+     * @param ignoreFields 忽略的属性数组
      */
-    public static void assertEquals(Object expected, Object actual) {
+    public static void assertEquals(Object expected, Object actual, String... ignoreFields) {
         Field[] expectedFields = ReflectUtil.getFields(expected.getClass());
         Arrays.stream(expectedFields).forEach(expectedField -> {
+            // 如果是忽略的属性,则不进行比对
+            if (ArrayUtil.contains(ignoreFields, expectedField.getName())) {
+                return;
+            }
             // 忽略不存在的属性
             Field actualField = ReflectUtil.getField(actual.getClass(), expectedField.getName());
             if (actualField == null) {

+ 25 - 30
src/test/java/cn/iocoder/dashboard/util/RandomUtils.java

@@ -1,9 +1,14 @@
 package cn.iocoder.dashboard.util;
 
-import cn.hutool.core.util.*;
+import cn.hutool.core.util.ArrayUtil;
+import cn.hutool.core.util.RandomUtil;
 import cn.iocoder.dashboard.modules.system.dal.dataobject.user.SysUserDO;
+import uk.co.jemos.podam.api.PodamFactory;
+import uk.co.jemos.podam.api.PodamFactoryImpl;
 
-import java.lang.reflect.Field;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.function.Consumer;
 
 /**
  * 随机工具类
@@ -14,6 +19,10 @@ public class RandomUtils {
 
     private static final int RANDOM_STRING_LENGTH = 10;
 
+    private static final int RANDOM_DATE_MAX = 30;
+
+    private static final PodamFactory PODAM_FACTORY = new PodamFactoryImpl();
+
     public static String randomString() {
         return RandomUtil.randomString(RANDOM_STRING_LENGTH);
     }
@@ -26,41 +35,27 @@ public class RandomUtils {
         return RandomUtil.randomInt(0, Integer.MAX_VALUE);
     }
 
+    public static Date randomDate() {
+        return RandomUtil.randomDay(0, RANDOM_DATE_MAX);
+    }
+
     public static Short randomShort() {
         return (short) RandomUtil.randomInt(0, Short.MAX_VALUE);
     }
 
-    public static SysUserDO randomUserDO() {
-        SysUserDO user = randomObject(SysUserDO.class);
-        return user;
+    @SafeVarargs
+    public static SysUserDO randomUserDO(Consumer<SysUserDO>... consumers) {
+        return randomPojo(SysUserDO.class, consumers);
     }
 
-    private static <T> T randomObject(Class<T> clazz) {
-        // 创建对象
-        T object = ReflectUtil.newInstance(clazz);
-        // 遍历属性,设置随机值
-        for (Field field : ReflectUtil.getFields(clazz)) {
-            // 数字类型
-            if (field.getType() == Long.class) {
-                ReflectUtil.setFieldValue(object, field, randomLong());
-                continue;
-            }
-            if (field.getType() == Integer.class) {
-                ReflectUtil.setFieldValue(object, field, randomInteger());
-                continue;
-            }
-            if (field.getType() == Short.class) {
-                ReflectUtil.setFieldValue(object, field, randomShort());
-                continue;
-            }
-            // 字符串类型
-            if (field.getType() == String.class) {
-                ReflectUtil.setFieldValue(object, field, randomString());
-                continue;
-            }
-//            System.out.println();
+    @SafeVarargs
+    private static <T> T randomPojo(Class<T> clazz, Consumer<T>... consumers) {
+        T pojo = PODAM_FACTORY.manufacturePojo(clazz);
+        // 非空时,回调逻辑。通过它,可以实现 Pojo 的进一步处理
+        if (ArrayUtil.isNotEmpty(consumers)) {
+            Arrays.stream(consumers).forEach(consumer -> consumer.accept(pojo));
         }
-        return object;
+        return pojo;
     }
 
 }