Commit ca1132f2df07a1c9e04379f75a7cb21f0e243cdc

Authored by neilz
1 parent 0775e85a

job 单元测试

src/main/java/cn/iocoder/dashboard/modules/infra/service/job/impl/InfJobServiceImpl.java
... ... @@ -13,7 +13,6 @@ import cn.iocoder.dashboard.modules.infra.dal.mysql.job.InfJobMapper;
13 13 import cn.iocoder.dashboard.modules.infra.enums.job.InfJobStatusEnum;
14 14 import cn.iocoder.dashboard.modules.infra.service.job.InfJobService;
15 15 import org.quartz.SchedulerException;
16   -import org.springframework.boot.test.mock.mockito.MockBean;
17 16 import org.springframework.stereotype.Service;
18 17 import org.springframework.transaction.annotation.Transactional;
19 18 import org.springframework.validation.annotation.Validated;
... ... @@ -38,7 +37,6 @@ public class InfJobServiceImpl implements InfJobService {
38 37 @Resource
39 38 private InfJobMapper jobMapper;
40 39  
41   - @MockBean
42 40 @Resource
43 41 private SchedulerManager schedulerManager;
44 42  
... ...
src/test/java/cn/iocoder/dashboard/modules/infra/service/job/InfJobLogServiceTest.java 0 → 100644
  1 +package cn.iocoder.dashboard.modules.infra.service.job;
  2 +
  3 +import static cn.hutool.core.util.RandomUtil.randomEle;
  4 +import static cn.iocoder.dashboard.util.AssertUtils.assertPojoEquals;
  5 +import static cn.iocoder.dashboard.util.RandomUtils.randomLongId;
  6 +import static cn.iocoder.dashboard.util.RandomUtils.randomPojo;
  7 +import static cn.iocoder.dashboard.util.RandomUtils.randomString;
  8 +import static cn.iocoder.dashboard.util.date.DateUtils.buildTime;
  9 +import static org.junit.jupiter.api.Assertions.assertEquals;
  10 +import static org.junit.jupiter.api.Assertions.assertNotNull;
  11 +
  12 +import java.util.ArrayList;
  13 +import java.util.List;
  14 +
  15 +import javax.annotation.Resource;
  16 +
  17 +import org.junit.jupiter.api.Test;
  18 +import org.springframework.context.annotation.Import;
  19 +
  20 +import cn.iocoder.dashboard.BaseDbUnitTest;
  21 +import cn.iocoder.dashboard.common.pojo.PageResult;
  22 +import cn.iocoder.dashboard.modules.infra.controller.job.vo.log.InfJobLogExportReqVO;
  23 +import cn.iocoder.dashboard.modules.infra.controller.job.vo.log.InfJobLogPageReqVO;
  24 +import cn.iocoder.dashboard.modules.infra.dal.dataobject.job.InfJobLogDO;
  25 +import cn.iocoder.dashboard.modules.infra.dal.mysql.job.InfJobLogMapper;
  26 +import cn.iocoder.dashboard.modules.infra.enums.job.InfJobLogStatusEnum;
  27 +import cn.iocoder.dashboard.modules.infra.service.job.impl.InfJobLogServiceImpl;
  28 +import cn.iocoder.dashboard.util.object.ObjectUtils;
  29 +
  30 +/**
  31 + * {@link InfJobLogServiceImpl} 的单元测试
  32 + *
  33 + * @author neilz
  34 + */
  35 +@Import(InfJobLogServiceImpl.class)
  36 +public class InfJobLogServiceTest extends BaseDbUnitTest {
  37 +
  38 + @Resource
  39 + private InfJobLogServiceImpl jobLogService;
  40 + @Resource
  41 + private InfJobLogMapper jobLogMapper;
  42 +
  43 + @Test
  44 + public void testCreateJobLog_success() {
  45 + // 准备参数
  46 + InfJobLogDO reqVO = randomPojo(InfJobLogDO.class, o -> {
  47 + o.setExecuteIndex(1);
  48 + });
  49 + // 调用
  50 + Long jobLogId = jobLogService.createJobLog(reqVO.getJobId(), reqVO.getBeginTime(), reqVO.getHandlerName(), reqVO.getHandlerParam(), reqVO.getExecuteIndex());
  51 + // 断言
  52 + assertNotNull(jobLogId);
  53 + // 校验记录的属性是否正确
  54 + InfJobLogDO job = jobLogMapper.selectById(jobLogId);
  55 + assertEquals(InfJobLogStatusEnum.RUNNING.getStatus(), job.getStatus());
  56 + }
  57 +
  58 + @Test
  59 + public void testUpdateJobLogResultAsync_success() {
  60 + // 准备参数
  61 + InfJobLogDO reqVO = randomPojo(InfJobLogDO.class, o -> {
  62 + o.setExecuteIndex(1);
  63 + });
  64 + InfJobLogDO log = InfJobLogDO.builder().jobId(reqVO.getJobId()).handlerName(reqVO.getHandlerName()).handlerParam(reqVO.getHandlerParam()).executeIndex(reqVO.getExecuteIndex())
  65 + .beginTime(reqVO.getBeginTime()).status(InfJobLogStatusEnum.RUNNING.getStatus()).build();
  66 + jobLogMapper.insert(log);
  67 + // 调用
  68 + jobLogService.updateJobLogResultAsync(log.getId(), reqVO.getBeginTime(), reqVO.getDuration(), true,reqVO.getResult());
  69 + // 校验记录的属性是否正确
  70 + InfJobLogDO job = jobLogMapper.selectById(log.getId());
  71 + assertEquals(InfJobLogStatusEnum.SUCCESS.getStatus(), job.getStatus());
  72 +
  73 + // 调用
  74 + jobLogService.updateJobLogResultAsync(log.getId(), reqVO.getBeginTime(), reqVO.getDuration(), false,reqVO.getResult());
  75 + // 校验记录的属性是否正确
  76 + InfJobLogDO job2 = jobLogMapper.selectById(log.getId());
  77 + assertEquals(InfJobLogStatusEnum.FAILURE.getStatus(), job2.getStatus());
  78 + }
  79 +
  80 + @Test
  81 + public void testGetJobLogListByIds_success() {
  82 + // mock 数据
  83 + InfJobLogDO dbJobLog = randomPojo(InfJobLogDO.class, o -> {
  84 + o.setExecuteIndex(1);
  85 + o.setStatus(randomEle(InfJobLogStatusEnum.values()).getStatus()); // 保证 status 的范围
  86 + });
  87 + InfJobLogDO cloneJobLog = ObjectUtils.clone(dbJobLog, o -> o.setHandlerName(randomString()));
  88 + jobLogMapper.insert(dbJobLog);
  89 + // 测试 handlerName 不匹配
  90 + jobLogMapper.insert(cloneJobLog);
  91 + // 准备参数
  92 + ArrayList ids = new ArrayList<>();
  93 + ids.add(dbJobLog.getId());
  94 + ids.add(cloneJobLog.getId());
  95 + // 调用
  96 + List<InfJobLogDO> list = jobLogService.getJobLogList(ids);
  97 + // 断言
  98 + assertEquals(2, list.size());
  99 + assertPojoEquals(dbJobLog, list.get(0));
  100 + }
  101 +
  102 + @Test
  103 + public void testGetJobPage_success() {
  104 + // mock 数据
  105 + InfJobLogDO dbJobLog = randomPojo(InfJobLogDO.class, o -> {
  106 + o.setExecuteIndex(1);
  107 + o.setHandlerName("handlerName 单元测试");
  108 + o.setStatus(InfJobLogStatusEnum.SUCCESS.getStatus());
  109 + o.setBeginTime(buildTime(2021, 1, 8));
  110 + o.setEndTime(buildTime(2021, 1, 8));
  111 + });
  112 + jobLogMapper.insert(dbJobLog);
  113 + // 测试 jobId 不匹配
  114 + jobLogMapper.insert(ObjectUtils.clone(dbJobLog, o -> o.setJobId(randomLongId())));
  115 + // 测试 handlerName 不匹配
  116 + jobLogMapper.insert(ObjectUtils.clone(dbJobLog, o -> o.setHandlerName(randomString())));
  117 + // 测试 beginTime 不匹配
  118 + jobLogMapper.insert(ObjectUtils.clone(dbJobLog, o -> o.setBeginTime(buildTime(2021, 1, 7))));
  119 + // 测试 endTime 不匹配
  120 + jobLogMapper.insert(ObjectUtils.clone(dbJobLog, o -> o.setEndTime(buildTime(2021, 1, 9))));
  121 + // 测试 status 不匹配
  122 + jobLogMapper.insert(ObjectUtils.clone(dbJobLog, o -> o.setStatus(InfJobLogStatusEnum.FAILURE.getStatus())));
  123 + // 准备参数
  124 + InfJobLogPageReqVO reqVo = new InfJobLogPageReqVO();
  125 + reqVo.setJobId(dbJobLog.getJobId());
  126 + reqVo.setHandlerName("单元");
  127 + reqVo.setBeginTime(dbJobLog.getBeginTime());
  128 + reqVo.setEndTime(dbJobLog.getEndTime());
  129 + reqVo.setStatus(InfJobLogStatusEnum.SUCCESS.getStatus());
  130 + // 调用
  131 + PageResult<InfJobLogDO> pageResult = jobLogService.getJobLogPage(reqVo);
  132 + // 断言
  133 + assertEquals(1, pageResult.getTotal());
  134 + assertEquals(1, pageResult.getList().size());
  135 + assertPojoEquals(dbJobLog, pageResult.getList().get(0));
  136 + }
  137 +
  138 + @Test
  139 + public void testGetJobListForExport_success() {
  140 + // mock 数据
  141 + InfJobLogDO dbJobLog = randomPojo(InfJobLogDO.class, o -> {
  142 + o.setExecuteIndex(1);
  143 + o.setHandlerName("handlerName 单元测试");
  144 + o.setStatus(InfJobLogStatusEnum.SUCCESS.getStatus());
  145 + o.setBeginTime(buildTime(2021, 1, 8));
  146 + o.setEndTime(buildTime(2021, 1, 8));
  147 + });
  148 + jobLogMapper.insert(dbJobLog);
  149 + // 测试 jobId 不匹配
  150 + jobLogMapper.insert(ObjectUtils.clone(dbJobLog, o -> o.setJobId(randomLongId())));
  151 + // 测试 handlerName 不匹配
  152 + jobLogMapper.insert(ObjectUtils.clone(dbJobLog, o -> o.setHandlerName(randomString())));
  153 + // 测试 beginTime 不匹配
  154 + jobLogMapper.insert(ObjectUtils.clone(dbJobLog, o -> o.setBeginTime(buildTime(2021, 1, 7))));
  155 + // 测试 endTime 不匹配
  156 + jobLogMapper.insert(ObjectUtils.clone(dbJobLog, o -> o.setEndTime(buildTime(2021, 1, 9))));
  157 + // 测试 status 不匹配
  158 + jobLogMapper.insert(ObjectUtils.clone(dbJobLog, o -> o.setStatus(InfJobLogStatusEnum.FAILURE.getStatus())));
  159 + // 准备参数
  160 + InfJobLogExportReqVO reqVo = new InfJobLogExportReqVO();
  161 + reqVo.setJobId(dbJobLog.getJobId());
  162 + reqVo.setHandlerName("单元");
  163 + reqVo.setBeginTime(dbJobLog.getBeginTime());
  164 + reqVo.setEndTime(dbJobLog.getEndTime());
  165 + reqVo.setStatus(InfJobLogStatusEnum.SUCCESS.getStatus());
  166 + // 调用
  167 + List<InfJobLogDO> list = jobLogService.getJobLogList(reqVo);
  168 + // 断言
  169 + assertEquals(1, list.size());
  170 + assertPojoEquals(dbJobLog, list.get(0));
  171 + }
  172 +
  173 +}
... ...
src/test/java/cn/iocoder/dashboard/modules/infra/service/job/InfJobServiceTest.java
1 1 package cn.iocoder.dashboard.modules.infra.service.job;
2 2  
  3 +import static cn.hutool.core.util.RandomUtil.randomEle;
  4 +import static cn.iocoder.dashboard.modules.infra.enums.InfErrorCodeConstants.JOB_CHANGE_STATUS_EQUALS;
  5 +import static cn.iocoder.dashboard.modules.infra.enums.InfErrorCodeConstants.JOB_CHANGE_STATUS_INVALID;
  6 +import static cn.iocoder.dashboard.modules.infra.enums.InfErrorCodeConstants.JOB_CRON_EXPRESSION_VALID;
  7 +import static cn.iocoder.dashboard.modules.infra.enums.InfErrorCodeConstants.JOB_HANDLER_EXISTS;
  8 +import static cn.iocoder.dashboard.modules.infra.enums.InfErrorCodeConstants.JOB_NOT_EXISTS;
  9 +import static cn.iocoder.dashboard.modules.infra.enums.InfErrorCodeConstants.JOB_UPDATE_ONLY_NORMAL_STATUS;
3 10 import static cn.iocoder.dashboard.util.AssertUtils.assertPojoEquals;
  11 +import static cn.iocoder.dashboard.util.AssertUtils.assertServiceException;
4 12 import static cn.iocoder.dashboard.util.RandomUtils.randomPojo;
  13 +import static cn.iocoder.dashboard.util.RandomUtils.randomString;
5 14 import static org.junit.jupiter.api.Assertions.assertEquals;
6 15 import static org.junit.jupiter.api.Assertions.assertNotNull;
7   -import static org.mockito.Mockito.times;
8   -import static org.mockito.Mockito.verify;
  16 +import static org.junit.jupiter.api.Assertions.assertNull;
  17 +
  18 +import java.util.ArrayList;
  19 +import java.util.List;
9 20  
10 21 import javax.annotation.Resource;
11 22  
12 23 import org.junit.jupiter.api.Test;
13 24 import org.quartz.SchedulerException;
  25 +import org.springframework.boot.test.mock.mockito.MockBean;
14 26 import org.springframework.context.annotation.Import;
  27 +
15 28 import cn.iocoder.dashboard.BaseDbUnitTest;
  29 +import cn.iocoder.dashboard.common.pojo.PageResult;
16 30 import cn.iocoder.dashboard.framework.quartz.core.scheduler.SchedulerManager;
17 31 import cn.iocoder.dashboard.modules.infra.controller.job.vo.job.InfJobCreateReqVO;
  32 +import cn.iocoder.dashboard.modules.infra.controller.job.vo.job.InfJobExportReqVO;
  33 +import cn.iocoder.dashboard.modules.infra.controller.job.vo.job.InfJobPageReqVO;
  34 +import cn.iocoder.dashboard.modules.infra.controller.job.vo.job.InfJobUpdateReqVO;
18 35 import cn.iocoder.dashboard.modules.infra.convert.job.InfJobConvert;
19 36 import cn.iocoder.dashboard.modules.infra.dal.dataobject.job.InfJobDO;
20 37 import cn.iocoder.dashboard.modules.infra.dal.mysql.job.InfJobMapper;
21 38 import cn.iocoder.dashboard.modules.infra.enums.job.InfJobStatusEnum;
22 39 import cn.iocoder.dashboard.modules.infra.service.job.impl.InfJobServiceImpl;
  40 +import cn.iocoder.dashboard.util.object.ObjectUtils;
23 41  
24 42 /**
25 43 * {@link InfJobServiceImpl} 的单元测试
... ... @@ -28,45 +46,236 @@ import cn.iocoder.dashboard.modules.infra.service.job.impl.InfJobServiceImpl;
28 46 */
29 47 @Import(InfJobServiceImpl.class)
30 48 public class InfJobServiceTest extends BaseDbUnitTest {
  49 +
31 50 @Resource
32 51 private InfJobServiceImpl jobService;
33   -
34 52 @Resource
35 53 private InfJobMapper jobMapper;
36   - @Resource
  54 + @MockBean
37 55 private SchedulerManager schedulerManager;
38 56  
39 57 @Test
40   - public void testCreateJob_success() throws SchedulerException {
41   - // 准备参数
  58 + public void testCreateJob_cronExpressionValid() {
  59 + // 准备参数。Cron 表达式为 String 类型,默认随机字符串。
42 60 InfJobCreateReqVO reqVO = randomPojo(InfJobCreateReqVO.class);
43   - reqVO.setCronExpression("0 0/1 * * * ? *");
  61 + // 调用,并断言异常
  62 + assertServiceException(() -> jobService.createJob(reqVO), JOB_CRON_EXPRESSION_VALID);
  63 + }
44 64  
  65 + @Test
  66 + public void testCreateJob_jobHandlerExists() throws SchedulerException {
  67 + // 准备参数 指定 Cron 表达式
  68 + InfJobCreateReqVO reqVO = randomPojo(InfJobCreateReqVO.class, o -> o.setCronExpression("0 0/1 * * * ? *"));
45 69 // 调用
46   - Long jobId = jobService.createJob(reqVO);
  70 + jobService.createJob(reqVO);
  71 + // 调用,并断言异常
  72 + assertServiceException(() -> jobService.createJob(reqVO), JOB_HANDLER_EXISTS);
  73 + }
47 74  
  75 + @Test
  76 + public void testCreateJob_success() throws SchedulerException {
  77 + // 准备参数 指定 Cron 表达式
  78 + InfJobCreateReqVO reqVO = randomPojo(InfJobCreateReqVO.class, o -> o.setCronExpression("0 0/1 * * * ? *"));
  79 + // 调用
  80 + Long jobId = jobService.createJob(reqVO);
48 81 // 断言
49 82 assertNotNull(jobId);
50   -
51 83 // 校验记录的属性是否正确
52 84 InfJobDO job = jobMapper.selectById(jobId);
53 85 assertPojoEquals(reqVO, job);
54 86 assertEquals(InfJobStatusEnum.NORMAL.getStatus(), job.getStatus());
  87 + }
  88 +
  89 + @Test
  90 + public void testUpdateJob_jobNotExists(){
  91 + // 准备参数
  92 + InfJobUpdateReqVO reqVO = randomPojo(InfJobUpdateReqVO.class, o -> o.setCronExpression("0 0/1 * * * ? *"));
  93 + // 调用,并断言异常
  94 + assertServiceException(() -> jobService.updateJob(reqVO), JOB_NOT_EXISTS);
  95 + }
  96 +
  97 + @Test
  98 + public void testUpdateJob_onlyNormalStatus(){
  99 + // mock 数据
  100 + InfJobCreateReqVO createReqVO = randomPojo(InfJobCreateReqVO.class, o -> o.setCronExpression("0 0/1 * * * ? *"));
  101 + InfJobDO job = InfJobConvert.INSTANCE.convert(createReqVO);
  102 + job.setStatus(InfJobStatusEnum.INIT.getStatus());
  103 + fillJobMonitorTimeoutEmpty(job);
  104 + jobMapper.insert(job);
  105 + // 准备参数
  106 + InfJobUpdateReqVO updateReqVO = randomPojo(InfJobUpdateReqVO.class, o -> {
  107 + o.setId(job.getId());
  108 + o.setName(createReqVO.getName());
  109 + o.setCronExpression(createReqVO.getCronExpression());
  110 + });
  111 + // 调用,并断言异常
  112 + assertServiceException(() -> jobService.updateJob(updateReqVO), JOB_UPDATE_ONLY_NORMAL_STATUS);
  113 + }
  114 +
  115 + @Test
  116 + public void testUpdateJob_success() throws SchedulerException {
  117 + // mock 数据
  118 + InfJobCreateReqVO createReqVO = randomPojo(InfJobCreateReqVO.class, o -> o.setCronExpression("0 0/1 * * * ? *"));
  119 + InfJobDO job = InfJobConvert.INSTANCE.convert(createReqVO);
  120 + job.setStatus(InfJobStatusEnum.NORMAL.getStatus());
  121 + fillJobMonitorTimeoutEmpty(job);
  122 + jobMapper.insert(job);
  123 + schedulerManager.addJob(job.getId(), job.getHandlerName(), job.getHandlerParam(), job.getCronExpression(),
  124 + createReqVO.getRetryCount(), createReqVO.getRetryInterval());
  125 + // 准备参数
  126 + InfJobUpdateReqVO updateReqVO = randomPojo(InfJobUpdateReqVO.class, o -> {
  127 + o.setId(job.getId());
  128 + o.setName(createReqVO.getName());
  129 + o.setCronExpression(createReqVO.getCronExpression());
  130 + });
  131 + // 调用
  132 + jobService.updateJob(updateReqVO);
  133 + // 校验记录的属性是否正确
  134 + InfJobDO updateJob = jobMapper.selectById(updateReqVO.getId());
  135 + assertPojoEquals(updateReqVO, updateJob);
  136 + }
  137 +
  138 + @Test
  139 + public void testUpdateJobStatus_changeStatusInvalid() {
  140 + // 调用,并断言异常
  141 + assertServiceException(() -> jobService.updateJobStatus(1l, InfJobStatusEnum.INIT.getStatus()), JOB_CHANGE_STATUS_INVALID);
  142 + }
55 143  
56   - // 校验调用
57   - verify(jobMapper, times(1)).selectByHandlerName(reqVO.getHandlerName());
  144 + @Test
  145 + public void testUpdateJobStatus_changeStatusEquals() {
  146 + // mock 数据
  147 + InfJobCreateReqVO createReqVO = randomPojo(InfJobCreateReqVO.class, o -> o.setCronExpression("0 0/1 * * * ? *"));
  148 + InfJobDO job = InfJobConvert.INSTANCE.convert(createReqVO);
  149 + job.setStatus(InfJobStatusEnum.NORMAL.getStatus());
  150 + fillJobMonitorTimeoutEmpty(job);
  151 + jobMapper.insert(job);
  152 + // 调用,并断言异常
  153 + assertServiceException(() -> jobService.updateJobStatus(job.getId(), job.getStatus()), JOB_CHANGE_STATUS_EQUALS);
  154 + }
58 155  
59   - InfJobDO insertJob = InfJobConvert.INSTANCE.convert(reqVO);
60   - insertJob.setStatus(InfJobStatusEnum.INIT.getStatus());
61   - fillJobMonitorTimeoutEmpty(insertJob);
62   - verify(jobMapper, times(1)).insert(insertJob);
  156 + @Test
  157 + public void testUpdateJobStatus_success() throws SchedulerException {
  158 + // mock 数据
  159 + InfJobCreateReqVO createReqVO = randomPojo(InfJobCreateReqVO.class, o -> o.setCronExpression("0 0/1 * * * ? *"));
  160 + InfJobDO job = InfJobConvert.INSTANCE.convert(createReqVO);
  161 + job.setStatus(InfJobStatusEnum.NORMAL.getStatus());
  162 + fillJobMonitorTimeoutEmpty(job);
  163 + jobMapper.insert(job);
  164 + schedulerManager.addJob(job.getId(), job.getHandlerName(), job.getHandlerParam(), job.getCronExpression(),
  165 + createReqVO.getRetryCount(), createReqVO.getRetryInterval());
  166 + // 调用
  167 + jobService.updateJobStatus(job.getId(), InfJobStatusEnum.STOP.getStatus());
  168 + // 校验记录的属性是否正确
  169 + InfJobDO updateJob = jobMapper.selectById(job.getId());
  170 + assertEquals(InfJobStatusEnum.STOP.getStatus(), updateJob.getStatus());
  171 + }
  172 +
  173 + /**
  174 + * 页面"执行一次"按钮功能集成测试发现问题:
  175 + * inf_job 表初始化任务 sysUserSessionTimeoutJob 点击报错,是因为 Job 并没有添加到 Quartz 中;
  176 + * 没有走 createJob 中 scheduler.scheduleJob() 这一步,报错任务找不到。
  177 + * // FINISHED Quartz 相关表新增初始化任务 sysUserSessionTimeoutJob sql
  178 + */
  179 + @Test
  180 + public void testTriggerJob_success() throws SchedulerException {
  181 + /**
  182 + * TODO 不知道是否要将 Quartz 相关 SQL 引入来做单元测试
  183 + * 1、schedulerManager.addJob sysUserSessionTimeoutJob
  184 + * 2、schedulerManager.triggerJob
  185 + * 3、check inf_job_log
  186 + */
  187 + }
  188 +
  189 + @Test
  190 + public void testDeleteJob_success() throws SchedulerException {
  191 + // mock 数据
  192 + InfJobCreateReqVO createReqVO = randomPojo(InfJobCreateReqVO.class, o -> o.setCronExpression("0 0/1 * * * ? *"));
  193 + InfJobDO job = InfJobConvert.INSTANCE.convert(createReqVO);
  194 + job.setStatus(InfJobStatusEnum.NORMAL.getStatus());
  195 + fillJobMonitorTimeoutEmpty(job);
  196 + jobMapper.insert(job);
  197 + schedulerManager.addJob(job.getId(), job.getHandlerName(), job.getHandlerParam(), job.getCronExpression(),
  198 + createReqVO.getRetryCount(), createReqVO.getRetryInterval());
  199 + // 调用 UPDATE inf_job SET deleted=1 WHERE id=? AND deleted=0
  200 + jobService.deleteJob(job.getId());
  201 + // 校验数据不存在了 WHERE id=? AND deleted=0 查询为空正常
  202 + assertNull(jobMapper.selectById(job.getId()));
  203 + }
63 204  
64   - verify(schedulerManager, times(1)).addJob(job.getId(), job.getHandlerName(), job.getHandlerParam(), job.getCronExpression(),
65   - job.getRetryCount(), job.getRetryInterval());
  205 + @Test
  206 + public void testGetJobListByIds_success() {
  207 + // mock 数据
  208 + InfJobDO dbJob = randomPojo(InfJobDO.class, o -> {
  209 + o.setStatus(randomEle(InfJobStatusEnum.values()).getStatus()); // 保证 status 的范围
  210 + });
  211 + InfJobDO cloneJob = ObjectUtils.clone(dbJob, o -> o.setHandlerName(randomString()));
  212 + jobMapper.insert(dbJob);
  213 + // 测试 handlerName 不匹配
  214 + jobMapper.insert(cloneJob);
  215 + // 准备参数
  216 + ArrayList ids = new ArrayList<>();
  217 + ids.add(dbJob.getId());
  218 + ids.add(cloneJob.getId());
  219 + // 调用
  220 + List<InfJobDO> list = jobService.getJobList(ids);
  221 + // 断言
  222 + assertEquals(2, list.size());
  223 + assertPojoEquals(dbJob, list.get(0));
  224 + }
66 225  
67   - InfJobDO updateObj = InfJobDO.builder().id(insertJob.getId()).status(InfJobStatusEnum.NORMAL.getStatus()).build();
68   - verify(jobMapper, times(1)).updateById(updateObj);
  226 + @Test
  227 + public void testGetJobPage_success() {
  228 + // mock 数据
  229 + InfJobDO dbJob = randomPojo(InfJobDO.class, o -> {
  230 + o.setName("定时任务测试");
  231 + o.setHandlerName("handlerName 单元测试");
  232 + o.setStatus(InfJobStatusEnum.INIT.getStatus());
  233 + });
  234 + jobMapper.insert(dbJob);
  235 + // 测试 name 不匹配
  236 + jobMapper.insert(ObjectUtils.clone(dbJob, o -> o.setName("土豆")));
  237 + // 测试 status 不匹配
  238 + jobMapper.insert(ObjectUtils.clone(dbJob, o -> o.setStatus(InfJobStatusEnum.NORMAL.getStatus())));
  239 + // 测试 handlerName 不匹配
  240 + jobMapper.insert(ObjectUtils.clone(dbJob, o -> o.setHandlerName(randomString())));
  241 + // 准备参数
  242 + InfJobPageReqVO reqVo = new InfJobPageReqVO();
  243 + reqVo.setName("定时");
  244 + reqVo.setStatus(InfJobStatusEnum.INIT.getStatus());
  245 + reqVo.setHandlerName("单元");
  246 + // 调用
  247 + PageResult<InfJobDO> pageResult = jobService.getJobPage(reqVo);
  248 + // 断言
  249 + assertEquals(1, pageResult.getTotal());
  250 + assertEquals(1, pageResult.getList().size());
  251 + assertPojoEquals(dbJob, pageResult.getList().get(0));
  252 + }
69 253  
  254 + @Test
  255 + public void testGetJobListForExport_success() {
  256 + // mock 数据
  257 + InfJobDO dbJob = randomPojo(InfJobDO.class, o -> {
  258 + o.setName("定时任务测试");
  259 + o.setHandlerName("handlerName 单元测试");
  260 + o.setStatus(InfJobStatusEnum.INIT.getStatus());
  261 + });
  262 + jobMapper.insert(dbJob);
  263 + // 测试 name 不匹配
  264 + jobMapper.insert(ObjectUtils.clone(dbJob, o -> o.setName("土豆")));
  265 + // 测试 status 不匹配
  266 + jobMapper.insert(ObjectUtils.clone(dbJob, o -> o.setStatus(InfJobStatusEnum.NORMAL.getStatus())));
  267 + // 测试 handlerName 不匹配
  268 + jobMapper.insert(ObjectUtils.clone(dbJob, o -> o.setHandlerName(randomString())));
  269 + // 准备参数
  270 + InfJobExportReqVO reqVo = new InfJobExportReqVO();
  271 + reqVo.setName("定时");
  272 + reqVo.setStatus(InfJobStatusEnum.INIT.getStatus());
  273 + reqVo.setHandlerName("单元");
  274 + // 调用
  275 + List<InfJobDO> list = jobService.getJobList(reqVo);
  276 + // 断言
  277 + assertEquals(1, list.size());
  278 + assertPojoEquals(dbJob, list.get(0));
70 279 }
71 280  
72 281 private static void fillJobMonitorTimeoutEmpty(InfJobDO job) {
... ...
src/test/resources/sql/clean.sql
... ... @@ -2,6 +2,7 @@
2 2 DELETE FROM "inf_config";
3 3 DELETE FROM "inf_file";
4 4 DELETE FROM "inf_job";
  5 +DELETE FROM "inf_job_log";
5 6  
6 7 -- sys 开头的 DB
7 8 DELETE FROM "sys_dept";
... ...
src/test/resources/sql/create_tables.sql
... ... @@ -29,24 +29,44 @@ CREATE TABLE IF NOT EXISTS &quot;inf_file&quot; (
29 29 PRIMARY KEY ("id")
30 30 ) COMMENT '文件表';
31 31  
32   -CREATE TABLE "inf_job" (
33   - "id" bigint(20) NOT NULL GENERATED BY DEFAULT AS IDENTITY COMMENT '任务编号',
34   - "name" varchar(32) NOT NULL COMMENT '任务名称',
35   - "status" tinyint(4) NOT NULL COMMENT '任务状态',
36   - "handler_name" varchar(64) NOT NULL COMMENT '处理器的名字',
37   - "handler_param" varchar(255) DEFAULT NULL COMMENT '处理器的参数',
38   - "cron_expression" varchar(32) NOT NULL COMMENT 'CRON 表达式',
39   - "retry_count" int(11) NOT NULL DEFAULT '0' COMMENT '重试次数',
40   - "retry_interval" int(11) NOT NULL DEFAULT '0' COMMENT '重试间隔',
41   - "monitor_timeout" int(11) NOT NULL DEFAULT '0' COMMENT '监控超时时间',
42   - "creator" varchar(64) DEFAULT '' COMMENT '创建者',
43   - "create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
44   - "updater" varchar(64) DEFAULT '' COMMENT '更新者',
45   - "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
46   - "deleted" bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
47   - PRIMARY KEY ("id")
  32 +CREATE TABLE IF NOT EXISTS "inf_job" (
  33 + "id" bigint(20) NOT NULL GENERATED BY DEFAULT AS IDENTITY COMMENT '任务编号',
  34 + "name" varchar(32) NOT NULL COMMENT '任务名称',
  35 + "status" tinyint(4) NOT NULL COMMENT '任务状态',
  36 + "handler_name" varchar(64) NOT NULL COMMENT '处理器的名字',
  37 + "handler_param" varchar(255) DEFAULT NULL COMMENT '处理器的参数',
  38 + "cron_expression" varchar(32) NOT NULL COMMENT 'CRON 表达式',
  39 + "retry_count" int(11) NOT NULL DEFAULT '0' COMMENT '重试次数',
  40 + "retry_interval" int(11) NOT NULL DEFAULT '0' COMMENT '重试间隔',
  41 + "monitor_timeout" int(11) NOT NULL DEFAULT '0' COMMENT '监控超时时间',
  42 + "creator" varchar(64) DEFAULT '' COMMENT '创建者',
  43 + "create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  44 + "updater" varchar(64) DEFAULT '' COMMENT '更新者',
  45 + "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  46 + "deleted" bit NOT NULL DEFAULT FALSE COMMENT '是否删除',
  47 + PRIMARY KEY ("id")
48 48 ) COMMENT='定时任务表';
49 49  
  50 +DROP TABLE IF EXISTS "inf_job_log";
  51 +CREATE TABLE "inf_job_log" (
  52 + "id" bigint(20) NOT NULL GENERATED BY DEFAULT AS IDENTITY COMMENT '日志编号',
  53 + "job_id" bigint(20) NOT NULL COMMENT '任务编号',
  54 + "handler_name" varchar(64) NOT NULL COMMENT '处理器的名字',
  55 + "handler_param" varchar(255) DEFAULT NULL COMMENT '处理器的参数',
  56 + "execute_index" tinyint(4) NOT NULL DEFAULT '1' COMMENT '第几次执行',
  57 + "begin_time" datetime NOT NULL COMMENT '开始执行时间',
  58 + "end_time" datetime DEFAULT NULL COMMENT '结束执行时间',
  59 + "duration" int(11) DEFAULT NULL COMMENT '执行时长',
  60 + "status" tinyint(4) NOT NULL COMMENT '任务状态',
  61 + "result" varchar(4000) DEFAULT '' COMMENT '结果数据',
  62 + "creator" varchar(64) DEFAULT '' COMMENT '创建者',
  63 + "create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  64 + "updater" varchar(64) DEFAULT '' COMMENT '更新者',
  65 + "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  66 + "deleted" bit(1) NOT NULL DEFAULT FALSE COMMENT '是否删除',
  67 + PRIMARY KEY ("id")
  68 +)COMMENT='定时任务日志表';
  69 +
50 70 -- sys 开头的 DB
51 71  
52 72 CREATE TABLE IF NOT EXISTS "sys_dept" (
... ...