Commit 32620fb3a7d5dd29943227f44bb55c5906225bbe
1 parent
4dc484f5
infra logger 单元测试 (issues I3A9GW)
Showing
11 changed files
with
463 additions
and
13 deletions
src/main/java/cn/iocoder/dashboard/framework/logger/apilog/core/service/ApiAccessLogFrameworkService.java
| ... | ... | @@ -3,6 +3,7 @@ package cn.iocoder.dashboard.framework.logger.apilog.core.service; |
| 3 | 3 | import cn.iocoder.dashboard.framework.logger.apilog.core.service.dto.ApiAccessLogCreateDTO; |
| 4 | 4 | |
| 5 | 5 | import javax.validation.Valid; |
| 6 | +import java.util.concurrent.Future; | |
| 6 | 7 | |
| 7 | 8 | /** |
| 8 | 9 | * API 访问日志 Framework Service 接口 |
| ... | ... | @@ -15,7 +16,8 @@ public interface ApiAccessLogFrameworkService { |
| 15 | 16 | * 创建 API 访问日志 |
| 16 | 17 | * |
| 17 | 18 | * @param createDTO 创建信息 |
| 19 | + * @return 是否创建成功 | |
| 18 | 20 | */ |
| 19 | - void createApiAccessLogAsync(@Valid ApiAccessLogCreateDTO createDTO); | |
| 21 | + Future<Boolean> createApiAccessLogAsync(@Valid ApiAccessLogCreateDTO createDTO); | |
| 20 | 22 | |
| 21 | 23 | } | ... | ... |
src/main/java/cn/iocoder/dashboard/framework/logger/apilog/core/service/ApiErrorLogFrameworkService.java
| ... | ... | @@ -3,6 +3,7 @@ package cn.iocoder.dashboard.framework.logger.apilog.core.service; |
| 3 | 3 | import cn.iocoder.dashboard.framework.logger.apilog.core.service.dto.ApiErrorLogCreateDTO; |
| 4 | 4 | |
| 5 | 5 | import javax.validation.Valid; |
| 6 | +import java.util.concurrent.Future; | |
| 6 | 7 | |
| 7 | 8 | /** |
| 8 | 9 | * API 错误日志 Framework Service 接口 |
| ... | ... | @@ -15,7 +16,8 @@ public interface ApiErrorLogFrameworkService { |
| 15 | 16 | * 创建 API 错误日志 |
| 16 | 17 | * |
| 17 | 18 | * @param createDTO 创建信息 |
| 19 | + * @return 是否创建成功 | |
| 18 | 20 | */ |
| 19 | - void createApiErrorLogAsync(@Valid ApiErrorLogCreateDTO createDTO); | |
| 21 | + Future<Boolean> createApiErrorLogAsync(@Valid ApiErrorLogCreateDTO createDTO); | |
| 20 | 22 | |
| 21 | 23 | } | ... | ... |
src/main/java/cn/iocoder/dashboard/modules/infra/controller/logger/vo/apierrorlog/InfApiErrorLogExportReqVO.java
| ... | ... | @@ -14,7 +14,7 @@ import static cn.iocoder.dashboard.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOU |
| 14 | 14 | public class InfApiErrorLogExportReqVO { |
| 15 | 15 | |
| 16 | 16 | @ApiModelProperty(value = "用户编号", example = "666") |
| 17 | - private Integer userId; | |
| 17 | + private Long userId; | |
| 18 | 18 | |
| 19 | 19 | @ApiModelProperty(value = "用户类型", example = "1") |
| 20 | 20 | private Integer userType; | ... | ... |
src/main/java/cn/iocoder/dashboard/modules/infra/controller/logger/vo/apierrorlog/InfApiErrorLogPageReqVO.java
| ... | ... | @@ -19,7 +19,7 @@ import static cn.iocoder.dashboard.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOU |
| 19 | 19 | public class InfApiErrorLogPageReqVO extends PageParam { |
| 20 | 20 | |
| 21 | 21 | @ApiModelProperty(value = "用户编号", example = "666") |
| 22 | - private Integer userId; | |
| 22 | + private Long userId; | |
| 23 | 23 | |
| 24 | 24 | @ApiModelProperty(value = "用户类型", example = "1") |
| 25 | 25 | private Integer userType; | ... | ... |
src/main/java/cn/iocoder/dashboard/modules/infra/dal/dataobject/logger/InfApiAccessLogDO.java
src/main/java/cn/iocoder/dashboard/modules/infra/dal/dataobject/logger/InfApiErrorLogDO.java
| ... | ... | @@ -30,7 +30,7 @@ public class InfApiErrorLogDO extends BaseDO { |
| 30 | 30 | /** |
| 31 | 31 | * 用户编号 |
| 32 | 32 | */ |
| 33 | - private Integer userId; | |
| 33 | + private Long userId; | |
| 34 | 34 | /** |
| 35 | 35 | * 链路追踪编号 |
| 36 | 36 | * |
| ... | ... | @@ -148,6 +148,6 @@ public class InfApiErrorLogDO extends BaseDO { |
| 148 | 148 | * |
| 149 | 149 | * 关联 {@link SysUserDO#getId()} |
| 150 | 150 | */ |
| 151 | - private Integer processUserId; | |
| 151 | + private Long processUserId; | |
| 152 | 152 | |
| 153 | 153 | } | ... | ... |
src/main/java/cn/iocoder/dashboard/modules/infra/service/logger/impl/InfApiAccessLogServiceImpl.java
| ... | ... | @@ -9,12 +9,13 @@ import cn.iocoder.dashboard.modules.infra.dal.dataobject.logger.InfApiAccessLogD |
| 9 | 9 | import cn.iocoder.dashboard.modules.infra.dal.mysql.logger.InfApiAccessLogMapper; |
| 10 | 10 | import cn.iocoder.dashboard.modules.infra.service.logger.InfApiAccessLogService; |
| 11 | 11 | import org.springframework.scheduling.annotation.Async; |
| 12 | +import org.springframework.scheduling.annotation.AsyncResult; | |
| 12 | 13 | import org.springframework.stereotype.Service; |
| 13 | 14 | import org.springframework.validation.annotation.Validated; |
| 14 | 15 | |
| 15 | 16 | import javax.annotation.Resource; |
| 16 | -import javax.validation.Valid; | |
| 17 | 17 | import java.util.List; |
| 18 | +import java.util.concurrent.Future; | |
| 18 | 19 | |
| 19 | 20 | /** |
| 20 | 21 | * API 访问日志 Service 实现类 |
| ... | ... | @@ -30,10 +31,11 @@ public class InfApiAccessLogServiceImpl implements InfApiAccessLogService { |
| 30 | 31 | |
| 31 | 32 | @Override |
| 32 | 33 | @Async |
| 33 | - public void createApiAccessLogAsync(ApiAccessLogCreateDTO createDTO) { | |
| 34 | + public Future<Boolean> createApiAccessLogAsync(ApiAccessLogCreateDTO createDTO) { | |
| 34 | 35 | // 插入 |
| 35 | 36 | InfApiAccessLogDO apiAccessLog = InfApiAccessLogConvert.INSTANCE.convert(createDTO); |
| 36 | - apiAccessLogMapper.insert(apiAccessLog); | |
| 37 | + int insert = apiAccessLogMapper.insert(apiAccessLog); | |
| 38 | + return new AsyncResult<>(insert == 1); | |
| 37 | 39 | } |
| 38 | 40 | |
| 39 | 41 | @Override | ... | ... |
src/main/java/cn/iocoder/dashboard/modules/infra/service/logger/impl/InfApiErrorLogServiceImpl.java
| ... | ... | @@ -10,12 +10,14 @@ import cn.iocoder.dashboard.modules.infra.dal.mysql.logger.InfApiErrorLogMapper; |
| 10 | 10 | import cn.iocoder.dashboard.modules.infra.enums.logger.InfApiErrorLogProcessStatusEnum; |
| 11 | 11 | import cn.iocoder.dashboard.modules.infra.service.logger.InfApiErrorLogService; |
| 12 | 12 | import org.springframework.scheduling.annotation.Async; |
| 13 | +import org.springframework.scheduling.annotation.AsyncResult; | |
| 13 | 14 | import org.springframework.stereotype.Service; |
| 14 | 15 | import org.springframework.validation.annotation.Validated; |
| 15 | 16 | |
| 16 | 17 | import javax.annotation.Resource; |
| 17 | 18 | import java.util.Date; |
| 18 | 19 | import java.util.List; |
| 20 | +import java.util.concurrent.Future; | |
| 19 | 21 | |
| 20 | 22 | import static cn.iocoder.dashboard.common.exception.util.ServiceExceptionUtil.exception; |
| 21 | 23 | import static cn.iocoder.dashboard.modules.infra.enums.InfErrorCodeConstants.API_ERROR_LOG_NOT_FOUND; |
| ... | ... | @@ -35,10 +37,11 @@ public class InfApiErrorLogServiceImpl implements InfApiErrorLogService { |
| 35 | 37 | |
| 36 | 38 | @Override |
| 37 | 39 | @Async |
| 38 | - public void createApiErrorLogAsync(ApiErrorLogCreateDTO createDTO) { | |
| 40 | + public Future<Boolean> createApiErrorLogAsync(ApiErrorLogCreateDTO createDTO) { | |
| 39 | 41 | InfApiErrorLogDO apiErrorLog = InfApiErrorLogConvert.INSTANCE.convert(createDTO); |
| 40 | 42 | apiErrorLog.setProcessStatus(InfApiErrorLogProcessStatusEnum.INIT.getStatus()); |
| 41 | - apiErrorLogMapper.insert(apiErrorLog); | |
| 43 | + int insert = apiErrorLogMapper.insert(apiErrorLog); | |
| 44 | + return new AsyncResult<>(insert == 1); | |
| 42 | 45 | } |
| 43 | 46 | |
| 44 | 47 | @Override |
| ... | ... | @@ -62,7 +65,7 @@ public class InfApiErrorLogServiceImpl implements InfApiErrorLogService { |
| 62 | 65 | } |
| 63 | 66 | // 标记处理 |
| 64 | 67 | apiErrorLogMapper.updateById(InfApiErrorLogDO.builder().id(id).processStatus(processStatus) |
| 65 | - .processUserId(processStatus).processTime(new Date()).build()); | |
| 68 | + .processUserId(processUserId).processTime(new Date()).build()); | |
| 66 | 69 | } |
| 67 | 70 | |
| 68 | 71 | } | ... | ... |
src/test/java/cn/iocoder/dashboard/modules/infra/service/logger/InfApiAccessLogServiceImplTest.java
0 → 100644
| 1 | +package cn.iocoder.dashboard.modules.infra.service.logger; | |
| 2 | + | |
| 3 | +import cn.hutool.core.util.RandomUtil; | |
| 4 | +import cn.iocoder.dashboard.BaseDbUnitTest; | |
| 5 | +import cn.iocoder.dashboard.common.enums.UserTypeEnum; | |
| 6 | +import cn.iocoder.dashboard.common.exception.enums.GlobalErrorCodeConstants; | |
| 7 | +import cn.iocoder.dashboard.common.pojo.PageResult; | |
| 8 | +import cn.iocoder.dashboard.framework.logger.apilog.core.service.dto.ApiAccessLogCreateDTO; | |
| 9 | +import cn.iocoder.dashboard.modules.infra.controller.logger.vo.apiaccesslog.InfApiAccessLogExportReqVO; | |
| 10 | +import cn.iocoder.dashboard.modules.infra.controller.logger.vo.apiaccesslog.InfApiAccessLogPageReqVO; | |
| 11 | +import cn.iocoder.dashboard.modules.infra.dal.dataobject.logger.InfApiAccessLogDO; | |
| 12 | +import cn.iocoder.dashboard.modules.infra.dal.mysql.logger.InfApiAccessLogMapper; | |
| 13 | +import cn.iocoder.dashboard.modules.infra.service.logger.impl.InfApiAccessLogServiceImpl; | |
| 14 | +import cn.iocoder.dashboard.util.RandomUtils; | |
| 15 | +import cn.iocoder.dashboard.util.object.ObjectUtils; | |
| 16 | +import org.junit.jupiter.api.Test; | |
| 17 | +import org.springframework.context.annotation.Import; | |
| 18 | + | |
| 19 | +import javax.annotation.Resource; | |
| 20 | +import java.util.Date; | |
| 21 | +import java.util.List; | |
| 22 | +import java.util.concurrent.Future; | |
| 23 | + | |
| 24 | +import static cn.iocoder.dashboard.util.AssertUtils.assertPojoEquals; | |
| 25 | +import static cn.iocoder.dashboard.util.date.DateUtils.buildTime; | |
| 26 | +import static org.junit.jupiter.api.Assertions.assertEquals; | |
| 27 | +import static org.junit.jupiter.api.Assertions.assertNotNull; | |
| 28 | + | |
| 29 | +/** | |
| 30 | + * {@link InfApiAccessLogServiceImpl} 单元测试 | |
| 31 | + */ | |
| 32 | +@Import(InfApiAccessLogServiceImpl.class) | |
| 33 | +public class InfApiAccessLogServiceImplTest extends BaseDbUnitTest { | |
| 34 | + | |
| 35 | + @Resource | |
| 36 | + private InfApiAccessLogService infApiAccessLogServiceImpl; | |
| 37 | + | |
| 38 | + @Resource | |
| 39 | + private InfApiAccessLogMapper infApiAccessLogMapper; | |
| 40 | + | |
| 41 | + | |
| 42 | + @Test | |
| 43 | + public void testCreateApiAccessLogAsync() throws Exception { | |
| 44 | + ApiAccessLogCreateDTO createDTO = RandomUtils.randomPojo( | |
| 45 | + ApiAccessLogCreateDTO.class, | |
| 46 | + dto -> dto.setUserType(RandomUtil.randomEle(UserTypeEnum.values()).getValue()) | |
| 47 | + ); | |
| 48 | + | |
| 49 | + // 执行service方法 | |
| 50 | + Future<Boolean> future = infApiAccessLogServiceImpl.createApiAccessLogAsync(createDTO); | |
| 51 | + | |
| 52 | + // 等异步执行完 | |
| 53 | + future.get(); | |
| 54 | + | |
| 55 | + InfApiAccessLogDO infApiAccessLogDO = infApiAccessLogMapper.selectOne(null); | |
| 56 | + // 断言 | |
| 57 | + assertNotNull(infApiAccessLogDO); | |
| 58 | + // 断言,忽略基本字段 | |
| 59 | + assertPojoEquals(createDTO, infApiAccessLogDO); | |
| 60 | + } | |
| 61 | + | |
| 62 | + | |
| 63 | + @Test | |
| 64 | + public void testGetApiAccessLogPage() { | |
| 65 | + // 构造测试数据 | |
| 66 | + long userId = 2233L; | |
| 67 | + int userType = UserTypeEnum.ADMIN.getValue(); | |
| 68 | + String applicationName = "ruoyi-test"; | |
| 69 | + String requestUrl = "foo"; | |
| 70 | + Date beginTime = buildTime(2021, 3, 13); | |
| 71 | + int duration = 1000; | |
| 72 | + int resultCode = GlobalErrorCodeConstants.SUCCESS.getCode(); | |
| 73 | + | |
| 74 | + InfApiAccessLogDO infApiAccessLogDO = RandomUtils.randomPojo(InfApiAccessLogDO.class, dto -> { | |
| 75 | + dto.setUserId(userId); | |
| 76 | + dto.setUserType(userType); | |
| 77 | + dto.setApplicationName(applicationName); | |
| 78 | + dto.setRequestUrl(requestUrl); | |
| 79 | + dto.setBeginTime(beginTime); | |
| 80 | + dto.setDuration(duration); | |
| 81 | + dto.setResultCode(resultCode); | |
| 82 | + }); | |
| 83 | + infApiAccessLogMapper.insert(infApiAccessLogDO); | |
| 84 | + | |
| 85 | + // 下面几个都是不匹配的数据 | |
| 86 | + // userId 不同的 | |
| 87 | + infApiAccessLogMapper.insert(ObjectUtils.clone(infApiAccessLogDO, logDO -> logDO.setUserId(3344L))); | |
| 88 | + // userType | |
| 89 | + infApiAccessLogMapper.insert(ObjectUtils.clone(infApiAccessLogDO, logDO -> logDO.setUserType(UserTypeEnum.MEMBER.getValue()))); | |
| 90 | + // applicationName 不同的 | |
| 91 | + infApiAccessLogMapper.insert(ObjectUtils.clone(infApiAccessLogDO, logDO -> logDO.setApplicationName("test"))); | |
| 92 | + // requestUrl 不同的 | |
| 93 | + infApiAccessLogMapper.insert(ObjectUtils.clone(infApiAccessLogDO, logDO -> logDO.setRequestUrl("bar"))); | |
| 94 | + // 构造一个早期时间 2021-02-06 00:00:00 | |
| 95 | + infApiAccessLogMapper.insert(ObjectUtils.clone(infApiAccessLogDO, logDO -> logDO.setBeginTime(buildTime(2021, 2, 6)))); | |
| 96 | + // duration 不同的 | |
| 97 | + infApiAccessLogMapper.insert(ObjectUtils.clone(infApiAccessLogDO, logDO -> logDO.setDuration(100))); | |
| 98 | + // resultCode 不同的 | |
| 99 | + infApiAccessLogMapper.insert(ObjectUtils.clone(infApiAccessLogDO, logDO -> logDO.setResultCode(2))); | |
| 100 | + | |
| 101 | + // 构造调用参数 | |
| 102 | + InfApiAccessLogPageReqVO reqVO = new InfApiAccessLogPageReqVO(); | |
| 103 | + reqVO.setUserId(userId); | |
| 104 | + reqVO.setUserType(userType); | |
| 105 | + reqVO.setApplicationName(applicationName); | |
| 106 | + reqVO.setRequestUrl(requestUrl); | |
| 107 | + reqVO.setBeginBeginTime(buildTime(2021, 3, 12)); | |
| 108 | + reqVO.setEndBeginTime(buildTime(2021, 3, 14)); | |
| 109 | + reqVO.setDuration(duration); | |
| 110 | + reqVO.setResultCode(resultCode); | |
| 111 | + | |
| 112 | + // 调用service方法 | |
| 113 | + PageResult<InfApiAccessLogDO> pageResult = infApiAccessLogServiceImpl.getApiAccessLogPage(reqVO); | |
| 114 | + | |
| 115 | + // 断言,只查到了一条符合条件的 | |
| 116 | + assertEquals(1, pageResult.getTotal()); | |
| 117 | + assertEquals(1, pageResult.getList().size()); | |
| 118 | + assertPojoEquals(infApiAccessLogDO, pageResult.getList().get(0)); | |
| 119 | + } | |
| 120 | + | |
| 121 | + @Test | |
| 122 | + public void testGetApiAccessLogList() { | |
| 123 | + // 构造测试数据 | |
| 124 | + long userId = 2233L; | |
| 125 | + int userType = UserTypeEnum.ADMIN.getValue(); | |
| 126 | + String applicationName = "ruoyi-test"; | |
| 127 | + String requestUrl = "foo"; | |
| 128 | + Date beginTime = buildTime(2021, 3, 13); | |
| 129 | + int duration = 1000; | |
| 130 | + int resultCode = GlobalErrorCodeConstants.SUCCESS.getCode(); | |
| 131 | + | |
| 132 | + InfApiAccessLogDO infApiAccessLogDO = RandomUtils.randomPojo(InfApiAccessLogDO.class, dto -> { | |
| 133 | + dto.setUserId(userId); | |
| 134 | + dto.setUserType(userType); | |
| 135 | + dto.setApplicationName(applicationName); | |
| 136 | + dto.setRequestUrl(requestUrl); | |
| 137 | + dto.setBeginTime(beginTime); | |
| 138 | + dto.setDuration(duration); | |
| 139 | + dto.setResultCode(resultCode); | |
| 140 | + }); | |
| 141 | + infApiAccessLogMapper.insert(infApiAccessLogDO); | |
| 142 | + | |
| 143 | + // 下面几个都是不匹配的数据 | |
| 144 | + // userId 不同的 | |
| 145 | + infApiAccessLogMapper.insert(ObjectUtils.clone(infApiAccessLogDO, logDO -> logDO.setUserId(3344L))); | |
| 146 | + // userType | |
| 147 | + infApiAccessLogMapper.insert(ObjectUtils.clone(infApiAccessLogDO, logDO -> logDO.setUserType(UserTypeEnum.MEMBER.getValue()))); | |
| 148 | + // applicationName 不同的 | |
| 149 | + infApiAccessLogMapper.insert(ObjectUtils.clone(infApiAccessLogDO, logDO -> logDO.setApplicationName("test"))); | |
| 150 | + // requestUrl 不同的 | |
| 151 | + infApiAccessLogMapper.insert(ObjectUtils.clone(infApiAccessLogDO, logDO -> logDO.setRequestUrl("bar"))); | |
| 152 | + // 构造一个早期时间 2021-02-06 00:00:00 | |
| 153 | + infApiAccessLogMapper.insert(ObjectUtils.clone(infApiAccessLogDO, logDO -> logDO.setBeginTime(buildTime(2021, 2, 6)))); | |
| 154 | + // duration 不同的 | |
| 155 | + infApiAccessLogMapper.insert(ObjectUtils.clone(infApiAccessLogDO, logDO -> logDO.setDuration(100))); | |
| 156 | + // resultCode 不同的 | |
| 157 | + infApiAccessLogMapper.insert(ObjectUtils.clone(infApiAccessLogDO, logDO -> logDO.setResultCode(2))); | |
| 158 | + | |
| 159 | + // 构造调用参数 | |
| 160 | + InfApiAccessLogExportReqVO reqVO = new InfApiAccessLogExportReqVO(); | |
| 161 | + reqVO.setUserId(userId); | |
| 162 | + reqVO.setUserType(userType); | |
| 163 | + reqVO.setApplicationName(applicationName); | |
| 164 | + reqVO.setRequestUrl(requestUrl); | |
| 165 | + reqVO.setBeginBeginTime(buildTime(2021, 3, 12)); | |
| 166 | + reqVO.setEndBeginTime(buildTime(2021, 3, 14)); | |
| 167 | + reqVO.setDuration(duration); | |
| 168 | + reqVO.setResultCode(resultCode); | |
| 169 | + | |
| 170 | + // 调用service方法 | |
| 171 | + List<InfApiAccessLogDO> list = infApiAccessLogServiceImpl.getApiAccessLogList(reqVO); | |
| 172 | + | |
| 173 | + // 断言,只查到了一条符合条件的 | |
| 174 | + assertEquals(1, list.size()); | |
| 175 | + assertPojoEquals(infApiAccessLogDO, list.get(0)); | |
| 176 | + } | |
| 177 | +} | ... | ... |
src/test/java/cn/iocoder/dashboard/modules/infra/service/logger/InfApiErrorLogServiceImplTest.java
0 → 100644
| 1 | +package cn.iocoder.dashboard.modules.infra.service.logger; | |
| 2 | + | |
| 3 | +import cn.hutool.core.util.RandomUtil; | |
| 4 | +import cn.iocoder.dashboard.BaseDbUnitTest; | |
| 5 | +import cn.iocoder.dashboard.common.enums.UserTypeEnum; | |
| 6 | +import cn.iocoder.dashboard.common.pojo.PageResult; | |
| 7 | +import cn.iocoder.dashboard.framework.logger.apilog.core.service.dto.ApiErrorLogCreateDTO; | |
| 8 | +import cn.iocoder.dashboard.modules.infra.controller.logger.vo.apierrorlog.InfApiErrorLogExportReqVO; | |
| 9 | +import cn.iocoder.dashboard.modules.infra.controller.logger.vo.apierrorlog.InfApiErrorLogPageReqVO; | |
| 10 | +import cn.iocoder.dashboard.modules.infra.dal.dataobject.logger.InfApiErrorLogDO; | |
| 11 | +import cn.iocoder.dashboard.modules.infra.dal.mysql.logger.InfApiErrorLogMapper; | |
| 12 | +import cn.iocoder.dashboard.modules.infra.enums.logger.InfApiErrorLogProcessStatusEnum; | |
| 13 | +import cn.iocoder.dashboard.modules.infra.service.logger.impl.InfApiErrorLogServiceImpl; | |
| 14 | +import cn.iocoder.dashboard.util.RandomUtils; | |
| 15 | +import cn.iocoder.dashboard.util.object.ObjectUtils; | |
| 16 | +import org.junit.jupiter.api.Test; | |
| 17 | +import org.springframework.context.annotation.Import; | |
| 18 | + | |
| 19 | +import javax.annotation.Resource; | |
| 20 | +import java.util.Date; | |
| 21 | +import java.util.List; | |
| 22 | +import java.util.concurrent.Future; | |
| 23 | + | |
| 24 | +import static cn.iocoder.dashboard.modules.infra.enums.InfErrorCodeConstants.API_ERROR_LOG_NOT_FOUND; | |
| 25 | +import static cn.iocoder.dashboard.modules.infra.enums.InfErrorCodeConstants.API_ERROR_LOG_PROCESSED; | |
| 26 | +import static cn.iocoder.dashboard.util.AssertUtils.assertPojoEquals; | |
| 27 | +import static cn.iocoder.dashboard.util.AssertUtils.assertServiceException; | |
| 28 | +import static cn.iocoder.dashboard.util.date.DateUtils.buildTime; | |
| 29 | +import static org.junit.jupiter.api.Assertions.assertEquals; | |
| 30 | +import static org.junit.jupiter.api.Assertions.assertNotNull; | |
| 31 | + | |
| 32 | +/** | |
| 33 | + * {@link InfApiErrorLogServiceImpl} 单元测试 | |
| 34 | + */ | |
| 35 | +@Import(InfApiErrorLogServiceImpl.class) | |
| 36 | +public class InfApiErrorLogServiceImplTest extends BaseDbUnitTest { | |
| 37 | + | |
| 38 | + @Resource | |
| 39 | + private InfApiErrorLogService infApiErrorLogServiceImpl; | |
| 40 | + | |
| 41 | + @Resource | |
| 42 | + private InfApiErrorLogMapper infApiErrorLogMapper; | |
| 43 | + | |
| 44 | + | |
| 45 | + @Test | |
| 46 | + public void testCreateApiErrorLogAsync() throws Exception { | |
| 47 | + ApiErrorLogCreateDTO createDTO = RandomUtils.randomPojo( | |
| 48 | + ApiErrorLogCreateDTO.class, | |
| 49 | + dto -> dto.setUserType(RandomUtil.randomEle(UserTypeEnum.values()).getValue()) | |
| 50 | + ); | |
| 51 | + | |
| 52 | + // 执行service方法 | |
| 53 | + Future<Boolean> future = infApiErrorLogServiceImpl.createApiErrorLogAsync(createDTO); | |
| 54 | + | |
| 55 | + // 等异步执行完 | |
| 56 | + future.get(); | |
| 57 | + | |
| 58 | + InfApiErrorLogDO infApiErrorLogDO = infApiErrorLogMapper.selectOne(null); | |
| 59 | + // 断言 | |
| 60 | + assertNotNull(infApiErrorLogDO); | |
| 61 | + // 断言,忽略基本字段 | |
| 62 | + assertPojoEquals(createDTO, infApiErrorLogDO); | |
| 63 | + } | |
| 64 | + | |
| 65 | + | |
| 66 | + @Test | |
| 67 | + public void testGetApiErrorLogPage() { | |
| 68 | + // 构造测试数据 | |
| 69 | + long userId = 2233L; | |
| 70 | + int userType = UserTypeEnum.ADMIN.getValue(); | |
| 71 | + String applicationName = "ruoyi-test"; | |
| 72 | + String requestUrl = "foo"; | |
| 73 | + Date beginTime = buildTime(2021, 3, 13); | |
| 74 | + int progressStatus = InfApiErrorLogProcessStatusEnum.INIT.getStatus(); | |
| 75 | + | |
| 76 | + InfApiErrorLogDO infApiErrorLogDO = RandomUtils.randomPojo(InfApiErrorLogDO.class, logDO -> { | |
| 77 | + logDO.setUserId(userId); | |
| 78 | + logDO.setUserType(userType); | |
| 79 | + logDO.setApplicationName(applicationName); | |
| 80 | + logDO.setRequestUrl(requestUrl); | |
| 81 | + logDO.setExceptionTime(beginTime); | |
| 82 | + logDO.setProcessStatus(progressStatus); | |
| 83 | + }); | |
| 84 | + infApiErrorLogMapper.insert(infApiErrorLogDO); | |
| 85 | + | |
| 86 | + // 下面几个都是不匹配的数据 | |
| 87 | + // userId 不同的 | |
| 88 | + infApiErrorLogMapper.insert(ObjectUtils.clone(infApiErrorLogDO, logDO -> logDO.setUserId(3344L))); | |
| 89 | + // userType | |
| 90 | + infApiErrorLogMapper.insert(ObjectUtils.clone(infApiErrorLogDO, logDO -> logDO.setUserType(UserTypeEnum.MEMBER.getValue()))); | |
| 91 | + // applicationName 不同的 | |
| 92 | + infApiErrorLogMapper.insert(ObjectUtils.clone(infApiErrorLogDO, logDO -> logDO.setApplicationName("test"))); | |
| 93 | + // requestUrl 不同的 | |
| 94 | + infApiErrorLogMapper.insert(ObjectUtils.clone(infApiErrorLogDO, logDO -> logDO.setRequestUrl("bar"))); | |
| 95 | + // 构造一个早期时间 2021-02-06 00:00:00 | |
| 96 | + infApiErrorLogMapper.insert(ObjectUtils.clone(infApiErrorLogDO, logDO -> logDO.setExceptionTime(buildTime(2021, 2, 6)))); | |
| 97 | + // progressStatus 不同的 | |
| 98 | + infApiErrorLogMapper.insert(ObjectUtils.clone(infApiErrorLogDO, logDO -> logDO.setProcessStatus(InfApiErrorLogProcessStatusEnum.DONE.getStatus()))); | |
| 99 | + | |
| 100 | + // 构造调用参数 | |
| 101 | + InfApiErrorLogPageReqVO reqVO = new InfApiErrorLogPageReqVO(); | |
| 102 | + reqVO.setUserId(userId); | |
| 103 | + reqVO.setUserType(userType); | |
| 104 | + reqVO.setApplicationName(applicationName); | |
| 105 | + reqVO.setRequestUrl(requestUrl); | |
| 106 | + reqVO.setBeginExceptionTime(buildTime(2021, 3, 12)); | |
| 107 | + reqVO.setEndExceptionTime(buildTime(2021, 3, 14)); | |
| 108 | + reqVO.setProcessStatus(progressStatus); | |
| 109 | + | |
| 110 | + // 调用service方法 | |
| 111 | + PageResult<InfApiErrorLogDO> pageResult = infApiErrorLogServiceImpl.getApiErrorLogPage(reqVO); | |
| 112 | + | |
| 113 | + // 断言,只查到了一条符合条件的 | |
| 114 | + assertEquals(1, pageResult.getTotal()); | |
| 115 | + assertEquals(1, pageResult.getList().size()); | |
| 116 | + assertPojoEquals(infApiErrorLogDO, pageResult.getList().get(0)); | |
| 117 | + } | |
| 118 | + | |
| 119 | + @Test | |
| 120 | + public void testGetApiErrorLogList() { | |
| 121 | + // 构造测试数据 | |
| 122 | + long userId = 2233L; | |
| 123 | + int userType = UserTypeEnum.ADMIN.getValue(); | |
| 124 | + String applicationName = "ruoyi-test"; | |
| 125 | + String requestUrl = "foo"; | |
| 126 | + Date beginTime = buildTime(2021, 3, 13); | |
| 127 | + int progressStatus = InfApiErrorLogProcessStatusEnum.INIT.getStatus(); | |
| 128 | + | |
| 129 | + InfApiErrorLogDO infApiErrorLogDO = RandomUtils.randomPojo(InfApiErrorLogDO.class, logDO -> { | |
| 130 | + logDO.setUserId(userId); | |
| 131 | + logDO.setUserType(userType); | |
| 132 | + logDO.setApplicationName(applicationName); | |
| 133 | + logDO.setRequestUrl(requestUrl); | |
| 134 | + logDO.setExceptionTime(beginTime); | |
| 135 | + logDO.setProcessStatus(progressStatus); | |
| 136 | + }); | |
| 137 | + infApiErrorLogMapper.insert(infApiErrorLogDO); | |
| 138 | + | |
| 139 | + // 下面几个都是不匹配的数据 | |
| 140 | + // userId 不同的 | |
| 141 | + infApiErrorLogMapper.insert(ObjectUtils.clone(infApiErrorLogDO, logDO -> logDO.setUserId(3344L))); | |
| 142 | + // userType | |
| 143 | + infApiErrorLogMapper.insert(ObjectUtils.clone(infApiErrorLogDO, logDO -> logDO.setUserType(UserTypeEnum.MEMBER.getValue()))); | |
| 144 | + // applicationName 不同的 | |
| 145 | + infApiErrorLogMapper.insert(ObjectUtils.clone(infApiErrorLogDO, logDO -> logDO.setApplicationName("test"))); | |
| 146 | + // requestUrl 不同的 | |
| 147 | + infApiErrorLogMapper.insert(ObjectUtils.clone(infApiErrorLogDO, logDO -> logDO.setRequestUrl("bar"))); | |
| 148 | + // 构造一个早期时间 2021-02-06 00:00:00 | |
| 149 | + infApiErrorLogMapper.insert(ObjectUtils.clone(infApiErrorLogDO, logDO -> logDO.setExceptionTime(buildTime(2021, 2, 6)))); | |
| 150 | + // progressStatus 不同的 | |
| 151 | + infApiErrorLogMapper.insert(ObjectUtils.clone(infApiErrorLogDO, logDO -> logDO.setProcessStatus(InfApiErrorLogProcessStatusEnum.DONE.getStatus()))); | |
| 152 | + | |
| 153 | + // 构造调用参数 | |
| 154 | + InfApiErrorLogExportReqVO reqVO = new InfApiErrorLogExportReqVO(); | |
| 155 | + reqVO.setUserId(userId); | |
| 156 | + reqVO.setUserType(userType); | |
| 157 | + reqVO.setApplicationName(applicationName); | |
| 158 | + reqVO.setRequestUrl(requestUrl); | |
| 159 | + reqVO.setBeginExceptionTime(buildTime(2021, 3, 12)); | |
| 160 | + reqVO.setEndExceptionTime(buildTime(2021, 3, 14)); | |
| 161 | + reqVO.setProcessStatus(progressStatus); | |
| 162 | + | |
| 163 | + // 调用service方法 | |
| 164 | + List<InfApiErrorLogDO> list = infApiErrorLogServiceImpl.getApiErrorLogList(reqVO); | |
| 165 | + | |
| 166 | + // 断言,只查到了一条符合条件的 | |
| 167 | + assertEquals(1, list.size()); | |
| 168 | + assertPojoEquals(infApiErrorLogDO, list.get(0)); | |
| 169 | + } | |
| 170 | + | |
| 171 | + | |
| 172 | + @Test | |
| 173 | + public void testUpdateApiErrorLogProcess() { | |
| 174 | + // 先构造两条数据,第一条用于抛出异常,第二条用于正常的执行update操作 | |
| 175 | + Long processUserId = 2233L; | |
| 176 | + | |
| 177 | + InfApiErrorLogDO first = RandomUtils.randomPojo(InfApiErrorLogDO.class, logDO -> { | |
| 178 | + logDO.setProcessUserId(processUserId); | |
| 179 | + logDO.setUserType(UserTypeEnum.ADMIN.getValue()); | |
| 180 | + logDO.setProcessStatus(InfApiErrorLogProcessStatusEnum.DONE.getStatus()); | |
| 181 | + }); | |
| 182 | + infApiErrorLogMapper.insert(first); | |
| 183 | + | |
| 184 | + InfApiErrorLogDO second = RandomUtils.randomPojo(InfApiErrorLogDO.class, logDO -> { | |
| 185 | + logDO.setProcessUserId(1122L); | |
| 186 | + logDO.setUserType(UserTypeEnum.ADMIN.getValue()); | |
| 187 | + logDO.setProcessStatus(InfApiErrorLogProcessStatusEnum.INIT.getStatus()); | |
| 188 | + }); | |
| 189 | + infApiErrorLogMapper.insert(second); | |
| 190 | + | |
| 191 | + Long firstId = first.getId(); | |
| 192 | + Long secondId = second.getId(); | |
| 193 | + | |
| 194 | + // 执行正常的 update 操作 | |
| 195 | + infApiErrorLogServiceImpl.updateApiErrorLogProcess(secondId, InfApiErrorLogProcessStatusEnum.DONE.getStatus(), processUserId); | |
| 196 | + InfApiErrorLogDO secondSelect = infApiErrorLogMapper.selectOne("id", secondId); | |
| 197 | + | |
| 198 | + // id 为 0 查询不到,应该抛出异常 API_ERROR_LOG_NOT_FOUND | |
| 199 | + assertServiceException(() -> infApiErrorLogServiceImpl.updateApiErrorLogProcess(0L, InfApiErrorLogProcessStatusEnum.DONE.getStatus(), processUserId), API_ERROR_LOG_NOT_FOUND); | |
| 200 | + // id 为 first 的 progressStatus 为 DONE ,应该抛出 API_ERROR_LOG_PROCESSED | |
| 201 | + assertServiceException(() -> infApiErrorLogServiceImpl.updateApiErrorLogProcess(firstId, InfApiErrorLogProcessStatusEnum.DONE.getStatus(), processUserId), API_ERROR_LOG_PROCESSED); | |
| 202 | + // 验证 progressStatus 是否修改成功 | |
| 203 | + assertEquals(InfApiErrorLogProcessStatusEnum.DONE.getStatus(), secondSelect.getProcessStatus()); | |
| 204 | + // 验证 progressUserId 是否修改成功 | |
| 205 | + assertEquals(processUserId, secondSelect.getProcessUserId()); | |
| 206 | + } | |
| 207 | +} | ... | ... |
src/test/resources/sql/create_tables.sql
| ... | ... | @@ -241,3 +241,60 @@ create table IF NOT EXISTS "sys_user" ( |
| 241 | 241 | "deleted" bit not null default false, |
| 242 | 242 | primary key ("id") |
| 243 | 243 | ) comment '用户信息表'; |
| 244 | + | |
| 245 | + | |
| 246 | +create table "inf_api_access_log" ( | |
| 247 | + "id" bigint not null GENERATED BY DEFAULT AS IDENTITY, | |
| 248 | + "trace_id" varchar(64) not null default '', | |
| 249 | + "user_id" bigint not null default '0', | |
| 250 | + "user_type" tinyint not null default '0', | |
| 251 | + "application_name" varchar(50) not null, | |
| 252 | + "request_method" varchar(16) not null default '', | |
| 253 | + "request_url" varchar(255) not null default '', | |
| 254 | + "request_params" varchar(8000) not null default '', | |
| 255 | + "user_ip" varchar(50) not null, | |
| 256 | + "user_agent" varchar(512) not null, | |
| 257 | + "begin_time" timestamp not null, | |
| 258 | + "end_time" timestamp not null, | |
| 259 | + "duration" integer not null, | |
| 260 | + "result_code" integer not null default '0', | |
| 261 | + "result_msg" varchar(512) default '', | |
| 262 | + "creator" varchar(64) default '', | |
| 263 | + "create_time" timestamp not null default current_timestamp, | |
| 264 | + "updater" varchar(64) default '', | |
| 265 | + "update_time" timestamp not null default current_timestamp, | |
| 266 | + "deleted" bit not null default false, | |
| 267 | + primary key ("id") | |
| 268 | +) comment 'API 访问日志表'; | |
| 269 | + | |
| 270 | + | |
| 271 | +create table "inf_api_error_log" ( | |
| 272 | + "id" integer not null GENERATED BY DEFAULT AS IDENTITY, | |
| 273 | + "trace_id" varchar(64) not null, | |
| 274 | + "user_id" bigint not null default '0', | |
| 275 | + "user_type" tinyint not null default '0', | |
| 276 | + "application_name" varchar(50) not null, | |
| 277 | + "request_method" varchar(16) not null, | |
| 278 | + "request_url" varchar(255) not null, | |
| 279 | + "request_params" varchar(8000) not null, | |
| 280 | + "user_ip" varchar(50) not null, | |
| 281 | + "user_agent" varchar(512) not null, | |
| 282 | + "exception_time" timestamp not null, | |
| 283 | + "exception_name" varchar(128) not null default '', | |
| 284 | + "exception_message" clob not null, | |
| 285 | + "exception_root_cause_message" clob not null, | |
| 286 | + "exception_stack_trace" clob not null, | |
| 287 | + "exception_class_name" varchar(512) not null, | |
| 288 | + "exception_file_name" varchar(512) not null, | |
| 289 | + "exception_method_name" varchar(512) not null, | |
| 290 | + "exception_line_number" integer not null, | |
| 291 | + "process_status" tinyint not null, | |
| 292 | + "process_time" timestamp default null, | |
| 293 | + "process_user_id" bigint default '0', | |
| 294 | + "creator" varchar(64) default '', | |
| 295 | + "create_time" timestamp not null default current_timestamp, | |
| 296 | + "updater" varchar(64) default '', | |
| 297 | + "update_time" timestamp not null default current_timestamp, | |
| 298 | + "deleted" bit not null default false, | |
| 299 | + primary key ("id") | |
| 300 | +) comment '系统异常日志'; | |
| 244 | 301 | \ No newline at end of file | ... | ... |