mirror of
https://gitee.com/huangge1199_admin/vue-pro.git
synced 2025-01-31 09:30:05 +08:00
完善 FileConfig 的单元测试
This commit is contained in:
parent
659023bb35
commit
cdcecd0d4a
@ -18,6 +18,7 @@ import cn.iocoder.yudao.module.infra.convert.file.FileConfigConvert;
|
||||
import cn.iocoder.yudao.module.infra.dal.dataobject.file.FileConfigDO;
|
||||
import cn.iocoder.yudao.module.infra.dal.mysql.file.FileConfigMapper;
|
||||
import cn.iocoder.yudao.module.infra.mq.producer.file.FileConfigProducer;
|
||||
import lombok.Getter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
@ -58,6 +59,7 @@ public class FileConfigServiceImpl implements FileConfigService {
|
||||
/**
|
||||
* 缓存菜单的最大更新时间,用于后续的增量轮询,判断是否有更新
|
||||
*/
|
||||
@Getter
|
||||
private volatile Date maxUpdateTime;
|
||||
|
||||
@Resource
|
||||
@ -65,6 +67,7 @@ public class FileConfigServiceImpl implements FileConfigService {
|
||||
/**
|
||||
* Master FileClient 对象,有且仅有一个,即 {@link FileConfigDO#getMaster()} 对应的
|
||||
*/
|
||||
@Getter
|
||||
private FileClient masterFileClient;
|
||||
|
||||
@Resource
|
||||
|
@ -1,25 +1,42 @@
|
||||
package cn.iocoder.yudao.module.infra.service.file;
|
||||
|
||||
import cn.hutool.core.map.MapUtil;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.file.core.client.FileClient;
|
||||
import cn.iocoder.yudao.framework.file.core.client.FileClientConfig;
|
||||
import cn.iocoder.yudao.framework.file.core.client.FileClientFactory;
|
||||
import cn.iocoder.yudao.framework.file.core.client.local.LocalFileClientConfig;
|
||||
import cn.iocoder.yudao.framework.file.core.enums.FileStorageEnum;
|
||||
import cn.iocoder.yudao.module.infra.controller.admin.file.vo.config.FileConfigCreateReqVO;
|
||||
import cn.iocoder.yudao.module.infra.controller.admin.file.vo.config.FileConfigPageReqVO;
|
||||
import cn.iocoder.yudao.module.infra.controller.admin.file.vo.config.FileConfigUpdateReqVO;
|
||||
import cn.iocoder.yudao.module.infra.dal.dataobject.file.FileConfigDO;
|
||||
import cn.iocoder.yudao.module.infra.dal.mysql.file.FileConfigMapper;
|
||||
import cn.iocoder.yudao.module.infra.mq.producer.file.FileConfigProducer;
|
||||
import cn.iocoder.yudao.module.infra.test.BaseDbUnitTest;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import lombok.Data;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.boot.test.mock.mockito.MockBean;
|
||||
import org.springframework.context.annotation.Import;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.validation.Validator;
|
||||
import java.io.Serializable;
|
||||
import java.util.Map;
|
||||
|
||||
import static cn.hutool.core.util.RandomUtil.randomEle;
|
||||
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.buildTime;
|
||||
import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId;
|
||||
import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.max;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomLongId;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo;
|
||||
import static cn.iocoder.yudao.module.infra.enums.ErrorCodeConstants.FILE_CONFIG_DELETE_FAIL_MASTER;
|
||||
import static cn.iocoder.yudao.module.infra.enums.ErrorCodeConstants.FILE_CONFIG_NOT_EXISTS;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
/**
|
||||
* {@link FileConfigServiceImpl} 的单元测试类
|
||||
@ -35,10 +52,44 @@ public class FileConfigServiceImplTest extends BaseDbUnitTest {
|
||||
@Resource
|
||||
private FileConfigMapper fileConfigMapper;
|
||||
|
||||
@MockBean
|
||||
private FileConfigProducer fileConfigProducer;
|
||||
@MockBean
|
||||
private Validator validator;
|
||||
@MockBean
|
||||
private FileClientFactory fileClientFactory;
|
||||
|
||||
@Test
|
||||
public void testInitLocalCache() {
|
||||
// mock 数据
|
||||
FileConfigDO configDO1 = randomFileConfigDO().setId(1L).setMaster(true);
|
||||
fileConfigMapper.insert(configDO1);
|
||||
FileConfigDO configDO2 = randomFileConfigDO().setId(2L).setMaster(false);
|
||||
fileConfigMapper.insert(configDO2);
|
||||
// mock fileClientFactory 获得 master
|
||||
FileClient masterFileClient = mock(FileClient.class);
|
||||
when(fileClientFactory.getFileClient(eq(1L))).thenReturn(masterFileClient);
|
||||
|
||||
// 调用
|
||||
fileConfigService.initFileClients();
|
||||
// 断言 fileClientFactory 调用
|
||||
verify(fileClientFactory).createOrUpdateFileClient(eq(1L),
|
||||
eq(configDO1.getStorage()), eq(configDO1.getConfig()));
|
||||
verify(fileClientFactory).createOrUpdateFileClient(eq(2L),
|
||||
eq(configDO2.getStorage()), eq(configDO2.getConfig()));
|
||||
assertSame(masterFileClient, fileConfigService.getMasterFileClient());
|
||||
// 断言 maxUpdateTime 缓存
|
||||
assertEquals(max(configDO1.getUpdateTime(), configDO2.getUpdateTime()),
|
||||
fileConfigService.getMaxUpdateTime());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateFileConfig_success() {
|
||||
// 准备参数
|
||||
FileConfigCreateReqVO reqVO = randomPojo(FileConfigCreateReqVO.class);
|
||||
Map<String, Object> config = MapUtil.<String, Object>builder().put("basePath", "/yunai")
|
||||
.put("domain", "https://www.iocoder.cn").build();
|
||||
FileConfigCreateReqVO reqVO = randomPojo(FileConfigCreateReqVO.class,
|
||||
o -> o.setStorage(FileStorageEnum.LOCAL.getStorage()).setConfig(config));
|
||||
|
||||
// 调用
|
||||
Long fileConfigId = fileConfigService.createFileConfig(reqVO);
|
||||
@ -46,24 +97,37 @@ public class FileConfigServiceImplTest extends BaseDbUnitTest {
|
||||
assertNotNull(fileConfigId);
|
||||
// 校验记录的属性是否正确
|
||||
FileConfigDO fileConfig = fileConfigMapper.selectById(fileConfigId);
|
||||
assertPojoEquals(reqVO, fileConfig);
|
||||
assertPojoEquals(reqVO, fileConfig, "config");
|
||||
assertFalse(fileConfig.getMaster());
|
||||
assertEquals("/yunai", ((LocalFileClientConfig) fileConfig.getConfig()).getBasePath());
|
||||
assertEquals("https://www.iocoder.cn", ((LocalFileClientConfig) fileConfig.getConfig()).getDomain());
|
||||
// verify 调用
|
||||
verify(fileConfigProducer).sendFileConfigRefreshMessage();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateFileConfig_success() {
|
||||
// mock 数据
|
||||
FileConfigDO dbFileConfig = randomPojo(FileConfigDO.class);
|
||||
FileConfigDO dbFileConfig = randomPojo(FileConfigDO.class, o -> o.setStorage(FileStorageEnum.LOCAL.getStorage())
|
||||
.setConfig(new LocalFileClientConfig().setBasePath("/yunai").setDomain("https://www.iocoder.cn")));
|
||||
fileConfigMapper.insert(dbFileConfig);// @Sql: 先插入出一条存在的数据
|
||||
// 准备参数
|
||||
FileConfigUpdateReqVO reqVO = randomPojo(FileConfigUpdateReqVO.class, o -> {
|
||||
o.setId(dbFileConfig.getId()); // 设置更新的 ID
|
||||
Map<String, Object> config = MapUtil.<String, Object>builder().put("basePath", "/yunai2")
|
||||
.put("domain", "https://doc.iocoder.cn").build();
|
||||
o.setConfig(config);
|
||||
});
|
||||
|
||||
// 调用
|
||||
fileConfigService.updateFileConfig(reqVO);
|
||||
// 校验是否更新正确
|
||||
FileConfigDO fileConfig = fileConfigMapper.selectById(reqVO.getId()); // 获取最新的
|
||||
assertPojoEquals(reqVO, fileConfig);
|
||||
assertPojoEquals(reqVO, fileConfig, "config");
|
||||
assertEquals("/yunai2", ((LocalFileClientConfig) fileConfig.getConfig()).getBasePath());
|
||||
assertEquals("https://doc.iocoder.cn", ((LocalFileClientConfig) fileConfig.getConfig()).getDomain());
|
||||
// verify 调用
|
||||
verify(fileConfigProducer).sendFileConfigRefreshMessage();
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -75,10 +139,33 @@ public class FileConfigServiceImplTest extends BaseDbUnitTest {
|
||||
assertServiceException(() -> fileConfigService.updateFileConfig(reqVO), FILE_CONFIG_NOT_EXISTS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateFileConfigMaster_success() {
|
||||
// mock 数据
|
||||
FileConfigDO dbFileConfig = randomFileConfigDO().setMaster(false);
|
||||
fileConfigMapper.insert(dbFileConfig);// @Sql: 先插入出一条存在的数据
|
||||
FileConfigDO masterFileConfig = randomFileConfigDO().setMaster(true);
|
||||
fileConfigMapper.insert(masterFileConfig);// @Sql: 先插入出一条存在的数据
|
||||
|
||||
// 调用
|
||||
fileConfigService.updateFileConfigMaster(dbFileConfig.getId());
|
||||
// 断言数据
|
||||
assertTrue(fileConfigMapper.selectById(dbFileConfig.getId()).getMaster());
|
||||
assertFalse(fileConfigMapper.selectById(masterFileConfig.getId()).getMaster());
|
||||
// verify 调用
|
||||
verify(fileConfigProducer).sendFileConfigRefreshMessage();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateFileConfigMaster_notExists() {
|
||||
// 调用, 并断言异常
|
||||
assertServiceException(() -> fileConfigService.updateFileConfigMaster(randomLongId()), FILE_CONFIG_NOT_EXISTS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteFileConfig_success() {
|
||||
// mock 数据
|
||||
FileConfigDO dbFileConfig = randomPojo(FileConfigDO.class);
|
||||
FileConfigDO dbFileConfig = randomFileConfigDO().setMaster(false);
|
||||
fileConfigMapper.insert(dbFileConfig);// @Sql: 先插入出一条存在的数据
|
||||
// 准备参数
|
||||
Long id = dbFileConfig.getId();
|
||||
@ -87,6 +174,8 @@ public class FileConfigServiceImplTest extends BaseDbUnitTest {
|
||||
fileConfigService.deleteFileConfig(id);
|
||||
// 校验数据不存在了
|
||||
assertNull(fileConfigMapper.selectById(id));
|
||||
// verify 调用
|
||||
verify(fileConfigProducer).sendFileConfigRefreshMessage();
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -99,27 +188,36 @@ public class FileConfigServiceImplTest extends BaseDbUnitTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
@Disabled // TODO 请修改 null 为需要的值,然后删除 @Disabled 注解
|
||||
public void testDeleteFileConfig_master() {
|
||||
// mock 数据
|
||||
FileConfigDO dbFileConfig = randomFileConfigDO().setMaster(true);
|
||||
fileConfigMapper.insert(dbFileConfig);// @Sql: 先插入出一条存在的数据
|
||||
// 准备参数
|
||||
Long id = dbFileConfig.getId();
|
||||
|
||||
// 调用, 并断言异常
|
||||
assertServiceException(() -> fileConfigService.deleteFileConfig(id), FILE_CONFIG_DELETE_FAIL_MASTER);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetFileConfigPage() {
|
||||
// mock 数据
|
||||
FileConfigDO dbFileConfig = randomPojo(FileConfigDO.class, o -> { // 等会查询到
|
||||
o.setName(null);
|
||||
o.setStorage(null);
|
||||
o.setCreateTime(null);
|
||||
});
|
||||
FileConfigDO dbFileConfig = randomFileConfigDO().setName("芋道源码")
|
||||
.setStorage(FileStorageEnum.LOCAL.getStorage());
|
||||
dbFileConfig.setCreateTime(buildTime(2022, 11, 11));// 等会查询到
|
||||
fileConfigMapper.insert(dbFileConfig);
|
||||
// 测试 name 不匹配
|
||||
fileConfigMapper.insert(cloneIgnoreId(dbFileConfig, o -> o.setName(null)));
|
||||
fileConfigMapper.insert(cloneIgnoreId(dbFileConfig, o -> o.setName("源码")));
|
||||
// 测试 storage 不匹配
|
||||
fileConfigMapper.insert(cloneIgnoreId(dbFileConfig, o -> o.setStorage(null)));
|
||||
fileConfigMapper.insert(cloneIgnoreId(dbFileConfig, o -> o.setStorage(FileStorageEnum.DB.getStorage())));
|
||||
// 测试 createTime 不匹配
|
||||
fileConfigMapper.insert(cloneIgnoreId(dbFileConfig, o -> o.setCreateTime(null)));
|
||||
fileConfigMapper.insert(cloneIgnoreId(dbFileConfig, o -> o.setCreateTime(buildTime(2022, 12, 12))));
|
||||
// 准备参数
|
||||
FileConfigPageReqVO reqVO = new FileConfigPageReqVO();
|
||||
reqVO.setName(null);
|
||||
reqVO.setStorage(null);
|
||||
reqVO.setBeginCreateTime(null);
|
||||
reqVO.setEndCreateTime(null);
|
||||
reqVO.setName("芋道");
|
||||
reqVO.setStorage(FileStorageEnum.LOCAL.getStorage());
|
||||
reqVO.setBeginCreateTime(buildTime(2022, 11, 10));
|
||||
reqVO.setEndCreateTime(buildTime(2022, 11, 12));
|
||||
|
||||
// 调用
|
||||
PageResult<FileConfigDO> pageResult = fileConfigService.getFileConfigPage(reqVO);
|
||||
@ -129,4 +227,30 @@ public class FileConfigServiceImplTest extends BaseDbUnitTest {
|
||||
assertPojoEquals(dbFileConfig, pageResult.getList().get(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFileConfig() {
|
||||
// mock 数据
|
||||
FileConfigDO dbFileConfig = randomFileConfigDO().setMaster(false);
|
||||
fileConfigMapper.insert(dbFileConfig);// @Sql: 先插入出一条存在的数据
|
||||
// 准备参数
|
||||
Long id = dbFileConfig.getId();
|
||||
// mock 获得 Client
|
||||
FileClient fileClient = mock(FileClient.class);
|
||||
when(fileClientFactory.getFileClient(eq(id))).thenReturn(fileClient);
|
||||
when(fileClient.upload(any(), any())).thenReturn("https://www.iocoder.cn");
|
||||
|
||||
// 调用,并断言
|
||||
assertEquals("https://www.iocoder.cn", fileConfigService.testFileConfig(id));
|
||||
}
|
||||
|
||||
private FileConfigDO randomFileConfigDO() {
|
||||
return randomPojo(FileConfigDO.class).setStorage(randomEle(FileStorageEnum.values()).getStorage())
|
||||
.setConfig(new EmptyFileClientConfig());
|
||||
}
|
||||
|
||||
@Data
|
||||
public static class EmptyFileClientConfig implements FileClientConfig, Serializable {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -26,8 +26,9 @@ spring:
|
||||
port: 16379 # 端口(单元测试,使用 16379 端口)
|
||||
database: 0 # 数据库索引
|
||||
|
||||
mybatis:
|
||||
mybatis-plus:
|
||||
lazy-initialization: true # 单元测试,设置 MyBatis Mapper 延迟加载,加速每个单元测试
|
||||
type-aliases-package: ${yudao.info.base-package}.module.*.dal.dataobject
|
||||
|
||||
--- #################### 定时任务相关配置 ####################
|
||||
|
||||
@ -46,4 +47,4 @@ mybatis:
|
||||
# 芋道配置项,设置当前项目所有自定义的配置
|
||||
yudao:
|
||||
info:
|
||||
base-package: cn.iocoder.yudao.module
|
||||
base-package: cn.iocoder.yudao
|
||||
|
@ -8,3 +8,4 @@ DELETE FROM "infra_api_access_log";
|
||||
DELETE FROM "infra_file";
|
||||
DELETE FROM "infra_api_error_log";
|
||||
DELETE FROM "infra_test_demo";
|
||||
DELETE FROM "infra_file_config";
|
||||
|
@ -16,6 +16,21 @@ CREATE TABLE IF NOT EXISTS "infra_config" (
|
||||
PRIMARY KEY ("id")
|
||||
) COMMENT '参数配置表';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS "infra_file_config" (
|
||||
"id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
|
||||
"name" varchar(63) NOT NULL,
|
||||
"storage" tinyint NOT NULL,
|
||||
"remark" varchar(255),
|
||||
"master" bit(1) NOT NULL,
|
||||
"config" varchar(4096) NOT NULL,
|
||||
"creator" varchar(64) DEFAULT '',
|
||||
"create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updater" varchar(64) DEFAULT '',
|
||||
"update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
"deleted" bit NOT NULL DEFAULT FALSE,
|
||||
PRIMARY KEY ("id")
|
||||
) COMMENT '文件配置表';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS "infra_file" (
|
||||
"id" varchar(188) NOT NULL,
|
||||
"type" varchar(63) DEFAULT NULL,
|
||||
|
Loading…
Reference in New Issue
Block a user