Commit 632be011b360142fc790bf8d6abc27045ce7ef10
1 parent
92997a0c
增加 podam 随机生成对象,简化单元测试的成本
Showing
7 changed files
with
55 additions
and
35 deletions
pom.xml
| ... | ... | @@ -190,6 +190,13 @@ |
| 190 | 190 | <scope>test</scope> |
| 191 | 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 | 201 | <dependency> |
| 195 | 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 | 122 | |
| 123 | 123 | private Properties buildProperties(List<InfConfigDO> configs) { |
| 124 | 124 | Properties properties = propertiesFactory.getPropertiesInstance(); |
| 125 | - configs.stream().filter(config -> 0 == config.getDeleted()) // 过滤掉被删除的配置 | |
| 125 | + configs.stream().filter(BaseDO::getDeleted) // 过滤掉被删除的配置 | |
| 126 | 126 | .forEach(config -> properties.put(config.getKey(), config.getValue())); |
| 127 | 127 | return properties; |
| 128 | 128 | } | ... | ... |
src/main/java/cn/iocoder/dashboard/framework/mybatis/core/dataobject/BaseDO.java
src/main/java/cn/iocoder/dashboard/modules/system/service/auth/impl/SysAuthServiceImpl.java
| ... | ... | @@ -85,7 +85,7 @@ public class SysAuthServiceImpl implements SysAuthService { |
| 85 | 85 | @Override |
| 86 | 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 | 91 | LoginUser loginUser = this.login0(reqVO.getUsername(), reqVO.getPassword()); |
| ... | ... | @@ -99,11 +99,13 @@ public class SysAuthServiceImpl implements SysAuthService { |
| 99 | 99 | String code = captchaService.getCaptchaCode(captchaUUID); |
| 100 | 100 | // 验证码不存在 |
| 101 | 101 | if (code == null) { |
| 102 | + // 创建登陆失败日志(验证码不存在) | |
| 102 | 103 | this.createLoginLog(username, SysLoginResultEnum.CAPTCHA_NOT_FOUND); |
| 103 | 104 | throw ServiceExceptionUtil.exception(AUTH_LOGIN_CAPTCHA_NOT_FOUND); |
| 104 | 105 | } |
| 105 | 106 | // 验证码不正确 |
| 106 | 107 | if (!code.equals(captchaCode)) { |
| 108 | + // 创建登陆失败日志(验证码不正确) | |
| 107 | 109 | this.createLoginLog(username, SysLoginResultEnum.CAPTCHA_CODE_ERROR); |
| 108 | 110 | throw ServiceExceptionUtil.exception(AUTH_LOGIN_CAPTCHA_CODE_ERROR); |
| 109 | 111 | } | ... | ... |
src/test/java/cn/iocoder/dashboard/modules/system/service/auth/SysAuthServiceImplTest.java
| 1 | 1 | package cn.iocoder.dashboard.modules.system.service.auth; |
| 2 | 2 | |
| 3 | 3 | import cn.iocoder.dashboard.BaseSpringBootUnitTest; |
| 4 | +import cn.iocoder.dashboard.framework.security.core.LoginUser; | |
| 4 | 5 | import cn.iocoder.dashboard.modules.system.dal.dataobject.user.SysUserDO; |
| 5 | 6 | import cn.iocoder.dashboard.modules.system.service.auth.impl.SysAuthServiceImpl; |
| 6 | 7 | import cn.iocoder.dashboard.modules.system.service.user.SysUserService; |
| 8 | +import cn.iocoder.dashboard.util.AssertUtils; | |
| 7 | 9 | import org.junit.jupiter.api.Test; |
| 8 | 10 | import org.springframework.boot.test.mock.mockito.MockBean; |
| 9 | 11 | |
| 10 | 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 | 17 | import static org.mockito.ArgumentMatchers.eq; |
| 14 | 18 | import static org.mockito.Mockito.when; |
| 15 | 19 | |
| ... | ... | @@ -28,6 +32,12 @@ public class SysAuthServiceImplTest extends BaseSpringBootUnitTest { |
| 28 | 32 | // mock 方法 |
| 29 | 33 | SysUserDO user = randomUserDO(); |
| 30 | 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 | 1 | package cn.iocoder.dashboard.util; |
| 2 | 2 | |
| 3 | +import cn.hutool.core.util.ArrayUtil; | |
| 3 | 4 | import cn.hutool.core.util.ReflectUtil; |
| 4 | 5 | import cn.iocoder.dashboard.common.exception.ErrorCode; |
| 5 | 6 | import cn.iocoder.dashboard.common.exception.ServiceException; |
| ... | ... | @@ -22,10 +23,15 @@ public class AssertUtils { |
| 22 | 23 | * |
| 23 | 24 | * @param expected 期望对象 |
| 24 | 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 | 29 | Field[] expectedFields = ReflectUtil.getFields(expected.getClass()); |
| 28 | 30 | Arrays.stream(expectedFields).forEach(expectedField -> { |
| 31 | + // 如果是忽略的属性,则不进行比对 | |
| 32 | + if (ArrayUtil.contains(ignoreFields, expectedField.getName())) { | |
| 33 | + return; | |
| 34 | + } | |
| 29 | 35 | // 忽略不存在的属性 |
| 30 | 36 | Field actualField = ReflectUtil.getField(actual.getClass(), expectedField.getName()); |
| 31 | 37 | if (actualField == null) { | ... | ... |
src/test/java/cn/iocoder/dashboard/util/RandomUtils.java
| 1 | 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 | 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 | 19 | |
| 15 | 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 | 26 | public static String randomString() { |
| 18 | 27 | return RandomUtil.randomString(RANDOM_STRING_LENGTH); |
| 19 | 28 | } |
| ... | ... | @@ -26,41 +35,27 @@ public class RandomUtils { |
| 26 | 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 | 42 | public static Short randomShort() { |
| 30 | 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 | } | ... | ... |