ソースを参照

修复所有单元测试

YunaiV 3 年 前
コミット
c58eb12896
31 ファイル変更219 行追加237 行削除
  1. 2 3
      yudao-module-bpm/yudao-module-bpm-base/src/test/java/cn/iocoder/yudao/module/bpm/test/BaseDbUnitTest.java
  2. 3 0
      yudao-module-bpm/yudao-module-bpm-base/src/test/resources/application-unit-test.yaml
  3. 0 1
      yudao-module-bpm/yudao-module-bpm-base/src/test/resources/sql/clean.sql
  4. 1 2
      yudao-module-bpm/yudao-module-bpm-base/src/test/resources/sql/create_tables.sql
  5. 0 1
      yudao-module-bpm/yudao-module-bpm-impl-activiti/src/test/java/cn/iocoder/yudao/module/bpm/test/BaseDbUnitTest.java
  6. 3 0
      yudao-module-bpm/yudao-module-bpm-impl-activiti/src/test/resources/application-unit-test.yaml
  7. 0 2
      yudao-module-bpm/yudao-module-bpm-impl-activiti/src/test/resources/sql/clean.sql
  8. 0 28
      yudao-module-bpm/yudao-module-bpm-impl-activiti/src/test/resources/sql/create_tables.sql
  9. 4 1
      yudao-module-infra/yudao-module-infra-impl/src/test/java/cn/iocoder/yudao/module/infra/test/BaseDbAndRedisUnitTest.java
  10. 2 1
      yudao-module-infra/yudao-module-infra-impl/src/test/java/cn/iocoder/yudao/module/infra/test/BaseDbUnitTest.java
  11. 0 30
      yudao-module-infra/yudao-module-infra-impl/src/test/java/cn/iocoder/yudao/module/infra/test/RedisTestConfiguration.java
  12. 3 0
      yudao-module-infra/yudao-module-infra-impl/src/test/resources/application-unit-test.yaml
  13. 4 1
      yudao-module-member/yudao-module-member-impl/src/test/java/cn/iocoder/yudao/module/member/test/BaseDbAndRedisUnitTest.java
  14. 2 1
      yudao-module-member/yudao-module-member-impl/src/test/java/cn/iocoder/yudao/module/member/test/BaseDbUnitTest.java
  15. 0 30
      yudao-module-member/yudao-module-member-impl/src/test/java/cn/iocoder/yudao/module/member/test/RedisTestConfiguration.java
  16. 3 0
      yudao-module-member/yudao-module-member-impl/src/test/resources/application-unit-test.yaml
  17. 4 1
      yudao-module-pay/yudao-module-pay-impl/src/test/java/cn/iocoder/yudao/module/pay/test/BaseDbAndRedisUnitTest.java
  18. 2 1
      yudao-module-pay/yudao-module-pay-impl/src/test/java/cn/iocoder/yudao/module/pay/test/BaseDbUnitTest.java
  19. 0 30
      yudao-module-pay/yudao-module-pay-impl/src/test/java/cn/iocoder/yudao/module/pay/test/RedisTestConfiguration.java
  20. 3 0
      yudao-module-pay/yudao-module-pay-impl/src/test/resources/application-unit-test.yaml
  21. 1 5
      yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/MenuController.java
  22. 9 0
      yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/service/permission/MenuService.java
  23. 11 0
      yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/service/permission/MenuServiceImpl.java
  24. 4 0
      yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/service/permission/RoleServiceImpl.java
  25. 75 45
      yudao-module-system/yudao-module-system-impl/src/test/java/cn/iocoder/yudao/module/system/service/permission/MenuServiceTest.java
  26. 0 1
      yudao-module-system/yudao-module-system-impl/src/test/java/cn/iocoder/yudao/module/system/service/permission/PermissionServiceTest.java
  27. 49 50
      yudao-module-system/yudao-module-system-impl/src/test/java/cn/iocoder/yudao/module/system/service/permission/RoleServiceTest.java
  28. 25 1
      yudao-module-system/yudao-module-system-impl/src/test/java/cn/iocoder/yudao/module/system/service/user/UserServiceImplTest.java
  29. 4 1
      yudao-module-system/yudao-module-system-impl/src/test/resources/sql/create_tables.sql
  30. 2 1
      yudao-module-tool/yudao-module-tool-impl/src/test/java/cn/iocoder/yudao/module/tool/test/BaseDbUnitTest.java
  31. 3 0
      yudao-module-tool/yudao-module-tool-impl/src/test/resources/application-unit-test.yaml

+ 2 - 3
yudao-module-bpm/yudao-module-bpm-base/src/test/java/cn/iocoder/yudao/module/bpm/test/BaseDbUnitTest.java

@@ -2,11 +2,11 @@ package cn.iocoder.yudao.module.bpm.test;
 
 import cn.iocoder.yudao.framework.datasource.config.YudaoDataSourceAutoConfiguration;
 import cn.iocoder.yudao.framework.mybatis.config.YudaoMybatisAutoConfiguration;
+import cn.iocoder.yudao.framework.test.config.SqlInitializationTestConfiguration;
 import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure;
 import com.baomidou.mybatisplus.autoconfigure.MybatisPlusAutoConfiguration;
 import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
 import org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration;
-import org.springframework.boot.autoconfigure.sql.init.SqlInitializationAutoConfiguration;
 import org.springframework.boot.test.context.SpringBootTest;
 import org.springframework.context.annotation.Import;
 import org.springframework.test.context.ActiveProfiles;
@@ -21,7 +21,6 @@ import org.springframework.test.context.jdbc.Sql;
  */
 @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE, classes = BaseDbUnitTest.Application.class)
 @ActiveProfiles("unit-test") // 设置使用 application-unit-test 配置文件
-@Sql(scripts = "/sql/create_tables.sql", executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD) // 每个单元测试结束前,创建表
 @Sql(scripts = "/sql/clean.sql", executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD) // 每个单元测试结束后,清理 DB
 public class BaseDbUnitTest {
 
@@ -31,7 +30,7 @@ public class BaseDbUnitTest {
             DataSourceAutoConfiguration.class, // Spring DB 自动配置类
             DataSourceTransactionManagerAutoConfiguration.class, // Spring 事务自动配置类
             DruidDataSourceAutoConfigure.class, // Druid 自动配置类
-            SqlInitializationAutoConfiguration.class,
+            SqlInitializationTestConfiguration.class, // SQL 初始化
             // MyBatis 配置类
             YudaoMybatisAutoConfiguration.class, // 自己的 MyBatis 配置类
             MybatisPlusAutoConfiguration.class, // MyBatis 的自动配置类

+ 3 - 0
yudao-module-bpm/yudao-module-bpm-base/src/test/resources/application-unit-test.yaml

@@ -16,6 +16,9 @@ spring:
     druid:
       async-init: true # 单元测试,异步初始化 Druid 连接池,提升启动速度
       initial-size: 1 # 单元测试,配置为 1,提升启动速度
+  sql:
+    init:
+      schema-locations: classpath:/sql/create_tables.sql
 
 mybatis:
   lazy-initialization: true # 单元测试,设置 MyBatis Mapper 延迟加载,加速每个单元测试

+ 0 - 1
yudao-module-bpm/yudao-module-bpm-base/src/test/resources/sql/clean.sql

@@ -1,3 +1,2 @@
--- bpm 开头的 DB
 DELETE FROM "bpm_form";
 DELETE FROM "bpm_user_group";

+ 1 - 2
yudao-module-bpm/yudao-module-bpm-base/src/test/resources/sql/create_tables.sql

@@ -1,4 +1,3 @@
--- bpm 开头的 DB
 CREATE TABLE IF NOT EXISTS "bpm_user_group" (
     "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
     "name" varchar(63) NOT NULL,
@@ -11,7 +10,7 @@ CREATE TABLE IF NOT EXISTS "bpm_user_group" (
     "update_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
     "deleted" bit NOT NULL DEFAULT FALSE,
     PRIMARY KEY ("id")
-    ) COMMENT '用户组';
+) COMMENT '用户组';
 
 CREATE TABLE IF NOT EXISTS "bpm_form" (
     "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,

+ 0 - 1
yudao-module-bpm/yudao-module-bpm-impl-activiti/src/test/java/cn/iocoder/yudao/module/bpm/test/BaseDbUnitTest.java

@@ -20,7 +20,6 @@ import org.springframework.test.context.jdbc.Sql;
  */
 @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE, classes = BaseDbUnitTest.Application.class)
 @ActiveProfiles("unit-test") // 设置使用 application-unit-test 配置文件
-@Sql(scripts = "/sql/create_tables.sql", executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD) // 每个单元测试结束前,创建表
 @Sql(scripts = "/sql/clean.sql", executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD) // 每个单元测试结束后,清理 DB
 public class BaseDbUnitTest {
 

+ 3 - 0
yudao-module-bpm/yudao-module-bpm-impl-activiti/src/test/resources/application-unit-test.yaml

@@ -16,6 +16,9 @@ spring:
     druid:
       async-init: true # 单元测试,异步初始化 Druid 连接池,提升启动速度
       initial-size: 1 # 单元测试,配置为 1,提升启动速度
+  sql:
+    init:
+      schema-locations: classpath:/sql/create_tables.sql
 
   # Redis 配置。Redisson 默认的配置足够使用,一般不需要进行调优
   redis:

+ 0 - 2
yudao-module-bpm/yudao-module-bpm-impl-activiti/src/test/resources/sql/clean.sql

@@ -1,2 +0,0 @@
--- bpm 开头的 DB
-DELETE FROM "bpm_form";

+ 0 - 28
yudao-module-bpm/yudao-module-bpm-impl-activiti/src/test/resources/sql/create_tables.sql

@@ -1,28 +0,0 @@
-CREATE TABLE IF NOT EXISTS "bpm_form" (
-    "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
-    "name" varchar(63) NOT NULL,
-    "status" tinyint NOT NULL,
-    "fields" varchar(255) NOT NULL,
-    "conf" varchar(255) NOT NULL,
-    "remark" varchar(255),
-    "creator" varchar(64) DEFAULT '',
-    "create_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
-    "updater" varchar(64) DEFAULT '',
-    "update_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
-    "deleted" bit NOT NULL DEFAULT FALSE,
-    PRIMARY KEY ("id")
-    ) COMMENT '动态表单';
-
-CREATE TABLE IF NOT EXISTS "bpm_user_group" (
-    "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
-    "name" varchar(63) NOT NULL,
-    "description" varchar(255) NOT NULL,
-    "status" tinyint NOT NULL,
-    "member_user_ids" varchar(255) NOT NULL,
-    "creator" varchar(64) DEFAULT '',
-    "create_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
-    "updater" varchar(64) DEFAULT '',
-    "update_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
-    "deleted" bit NOT NULL DEFAULT FALSE,
-    PRIMARY KEY ("id")
-    ) COMMENT '用户组';

+ 4 - 1
yudao-module-infra/yudao-module-infra-impl/src/test/java/cn/iocoder/yudao/module/infra/test/BaseDbAndRedisUnitTest.java

@@ -3,6 +3,8 @@ package cn.iocoder.yudao.module.infra.test;
 import cn.iocoder.yudao.framework.datasource.config.YudaoDataSourceAutoConfiguration;
 import cn.iocoder.yudao.framework.mybatis.config.YudaoMybatisAutoConfiguration;
 import cn.iocoder.yudao.framework.redis.config.YudaoRedisAutoConfiguration;
+import cn.iocoder.yudao.framework.test.config.RedisTestConfiguration;
+import cn.iocoder.yudao.framework.test.config.SqlInitializationTestConfiguration;
 import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure;
 import com.baomidou.mybatisplus.autoconfigure.MybatisPlusAutoConfiguration;
 import org.redisson.spring.starter.RedissonAutoConfiguration;
@@ -23,7 +25,6 @@ import org.springframework.test.context.jdbc.Sql;
  */
 @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE, classes = BaseDbAndRedisUnitTest.Application.class)
 @ActiveProfiles("unit-test") // 设置使用 application-unit-test 配置文件
-@Sql(scripts = "/sql/create_tables.sql", executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD) // 每个单元测试结束前,创建表
 @Sql(scripts = "/sql/clean.sql", executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD) // 每个单元测试结束后,清理 DB
 public class BaseDbAndRedisUnitTest {
 
@@ -33,9 +34,11 @@ public class BaseDbAndRedisUnitTest {
             DataSourceAutoConfiguration.class, // Spring DB 自动配置类
             DataSourceTransactionManagerAutoConfiguration.class, // Spring 事务自动配置类
             DruidDataSourceAutoConfigure.class, // Druid 自动配置类
+            SqlInitializationTestConfiguration.class, // SQL 初始化
             // MyBatis 配置类
             YudaoMybatisAutoConfiguration.class, // 自己的 MyBatis 配置类
             MybatisPlusAutoConfiguration.class, // MyBatis 的自动配置类
+
             // Redis 配置类
             RedisTestConfiguration.class, // Redis 测试配置类,用于启动 RedisServer
             RedisAutoConfiguration.class, // Spring Redis 自动配置类

+ 2 - 1
yudao-module-infra/yudao-module-infra-impl/src/test/java/cn/iocoder/yudao/module/infra/test/BaseDbUnitTest.java

@@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.infra.test;
 
 import cn.iocoder.yudao.framework.datasource.config.YudaoDataSourceAutoConfiguration;
 import cn.iocoder.yudao.framework.mybatis.config.YudaoMybatisAutoConfiguration;
+import cn.iocoder.yudao.framework.test.config.SqlInitializationTestConfiguration;
 import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure;
 import com.baomidou.mybatisplus.autoconfigure.MybatisPlusAutoConfiguration;
 import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
@@ -20,7 +21,6 @@ import org.springframework.test.context.jdbc.Sql;
  */
 @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE, classes = BaseDbUnitTest.Application.class)
 @ActiveProfiles("unit-test") // 设置使用 application-unit-test 配置文件
-@Sql(scripts = "/sql/create_tables.sql", executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD) // 每个单元测试结束前,创建表
 @Sql(scripts = "/sql/clean.sql", executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD) // 每个单元测试结束后,清理 DB
 public class BaseDbUnitTest {
 
@@ -30,6 +30,7 @@ public class BaseDbUnitTest {
             DataSourceAutoConfiguration.class, // Spring DB 自动配置类
             DataSourceTransactionManagerAutoConfiguration.class, // Spring 事务自动配置类
             DruidDataSourceAutoConfigure.class, // Druid 自动配置类
+            SqlInitializationTestConfiguration.class, // SQL 初始化
             // MyBatis 配置类
             YudaoMybatisAutoConfiguration.class, // 自己的 MyBatis 配置类
             MybatisPlusAutoConfiguration.class, // MyBatis 的自动配置类

+ 0 - 30
yudao-module-infra/yudao-module-infra-impl/src/test/java/cn/iocoder/yudao/module/infra/test/RedisTestConfiguration.java

@@ -1,30 +0,0 @@
-package cn.iocoder.yudao.module.infra.test;
-
-import com.github.fppt.jedismock.RedisServer;
-import org.springframework.boot.autoconfigure.data.redis.RedisProperties;
-import org.springframework.boot.context.properties.EnableConfigurationProperties;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.context.annotation.Lazy;
-
-import java.io.IOException;
-
-@Configuration(proxyBeanMethods = false)
-@Lazy(false) // 禁止延迟加载
-@EnableConfigurationProperties(RedisProperties.class)
-public class RedisTestConfiguration {
-
-    /**
-     * 创建模拟的 Redis Server 服务器
-     */
-    @Bean
-    public RedisServer redisServer(RedisProperties properties) throws IOException {
-        RedisServer redisServer = new RedisServer(properties.getPort());
-        // TODO 芋艿:一次执行多个单元测试时,貌似创建多个 spring 容器,导致不进行 stop。这样,就导致端口被占用,无法启动。。。
-        try {
-            redisServer.start();
-        } catch (Exception ignore) {}
-        return redisServer;
-    }
-
-}

+ 3 - 0
yudao-module-infra/yudao-module-infra-impl/src/test/resources/application-unit-test.yaml

@@ -16,6 +16,9 @@ spring:
     druid:
       async-init: true # 单元测试,异步初始化 Druid 连接池,提升启动速度
       initial-size: 1 # 单元测试,配置为 1,提升启动速度
+  sql:
+    init:
+      schema-locations: classpath:/sql/create_tables.sql
 
   # Redis 配置。Redisson 默认的配置足够使用,一般不需要进行调优
   redis:

+ 4 - 1
yudao-module-member/yudao-module-member-impl/src/test/java/cn/iocoder/yudao/module/member/test/BaseDbAndRedisUnitTest.java

@@ -3,6 +3,8 @@ package cn.iocoder.yudao.module.member.test;
 import cn.iocoder.yudao.framework.datasource.config.YudaoDataSourceAutoConfiguration;
 import cn.iocoder.yudao.framework.mybatis.config.YudaoMybatisAutoConfiguration;
 import cn.iocoder.yudao.framework.redis.config.YudaoRedisAutoConfiguration;
+import cn.iocoder.yudao.framework.test.config.RedisTestConfiguration;
+import cn.iocoder.yudao.framework.test.config.SqlInitializationTestConfiguration;
 import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure;
 import com.baomidou.mybatisplus.autoconfigure.MybatisPlusAutoConfiguration;
 import org.redisson.spring.starter.RedissonAutoConfiguration;
@@ -23,7 +25,6 @@ import org.springframework.test.context.jdbc.Sql;
  */
 @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE, classes = BaseDbAndRedisUnitTest.Application.class)
 @ActiveProfiles("unit-test") // 设置使用 application-unit-test 配置文件
-@Sql(scripts = "/sql/create_tables.sql", executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD) // 每个单元测试结束前,创建表
 @Sql(scripts = "/sql/clean.sql", executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD) // 每个单元测试结束后,清理 DB
 public class BaseDbAndRedisUnitTest {
 
@@ -33,9 +34,11 @@ public class BaseDbAndRedisUnitTest {
             DataSourceAutoConfiguration.class, // Spring DB 自动配置类
             DataSourceTransactionManagerAutoConfiguration.class, // Spring 事务自动配置类
             DruidDataSourceAutoConfigure.class, // Druid 自动配置类
+            SqlInitializationTestConfiguration.class, // SQL 初始化
             // MyBatis 配置类
             YudaoMybatisAutoConfiguration.class, // 自己的 MyBatis 配置类
             MybatisPlusAutoConfiguration.class, // MyBatis 的自动配置类
+
             // Redis 配置类
             RedisTestConfiguration.class, // Redis 测试配置类,用于启动 RedisServer
             RedisAutoConfiguration.class, // Spring Redis 自动配置类

+ 2 - 1
yudao-module-member/yudao-module-member-impl/src/test/java/cn/iocoder/yudao/module/member/test/BaseDbUnitTest.java

@@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.member.test;
 
 import cn.iocoder.yudao.framework.datasource.config.YudaoDataSourceAutoConfiguration;
 import cn.iocoder.yudao.framework.mybatis.config.YudaoMybatisAutoConfiguration;
+import cn.iocoder.yudao.framework.test.config.SqlInitializationTestConfiguration;
 import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure;
 import com.baomidou.mybatisplus.autoconfigure.MybatisPlusAutoConfiguration;
 import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
@@ -20,7 +21,6 @@ import org.springframework.test.context.jdbc.Sql;
  */
 @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE, classes = BaseDbUnitTest.Application.class)
 @ActiveProfiles("unit-test") // 设置使用 application-unit-test 配置文件
-@Sql(scripts = "/sql/create_tables.sql", executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD) // 每个单元测试结束前,创建表
 @Sql(scripts = "/sql/clean.sql", executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD) // 每个单元测试结束后,清理 DB
 public class BaseDbUnitTest {
 
@@ -30,6 +30,7 @@ public class BaseDbUnitTest {
             DataSourceAutoConfiguration.class, // Spring DB 自动配置类
             DataSourceTransactionManagerAutoConfiguration.class, // Spring 事务自动配置类
             DruidDataSourceAutoConfigure.class, // Druid 自动配置类
+            SqlInitializationTestConfiguration.class, // SQL 初始化
             // MyBatis 配置类
             YudaoMybatisAutoConfiguration.class, // 自己的 MyBatis 配置类
             MybatisPlusAutoConfiguration.class, // MyBatis 的自动配置类

+ 0 - 30
yudao-module-member/yudao-module-member-impl/src/test/java/cn/iocoder/yudao/module/member/test/RedisTestConfiguration.java

@@ -1,30 +0,0 @@
-package cn.iocoder.yudao.module.member.test;
-
-import com.github.fppt.jedismock.RedisServer;
-import org.springframework.boot.autoconfigure.data.redis.RedisProperties;
-import org.springframework.boot.context.properties.EnableConfigurationProperties;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.context.annotation.Lazy;
-
-import java.io.IOException;
-
-@Configuration(proxyBeanMethods = false)
-@Lazy(false) // 禁止延迟加载
-@EnableConfigurationProperties(RedisProperties.class)
-public class RedisTestConfiguration {
-
-    /**
-     * 创建模拟的 Redis Server 服务器
-     */
-    @Bean
-    public RedisServer redisServer(RedisProperties properties) throws IOException {
-        RedisServer redisServer = new RedisServer(properties.getPort());
-        // TODO 芋艿:一次执行多个单元测试时,貌似创建多个 spring 容器,导致不进行 stop。这样,就导致端口被占用,无法启动。。。
-        try {
-            redisServer.start();
-        } catch (Exception ignore) {}
-        return redisServer;
-    }
-
-}

+ 3 - 0
yudao-module-member/yudao-module-member-impl/src/test/resources/application-unit-test.yaml

@@ -16,6 +16,9 @@ spring:
     druid:
       async-init: true # 单元测试,异步初始化 Druid 连接池,提升启动速度
       initial-size: 1 # 单元测试,配置为 1,提升启动速度
+  sql:
+    init:
+      schema-locations: classpath:/sql/create_tables.sql
 
   # Redis 配置。Redisson 默认的配置足够使用,一般不需要进行调优
   redis:

+ 4 - 1
yudao-module-pay/yudao-module-pay-impl/src/test/java/cn/iocoder/yudao/module/pay/test/BaseDbAndRedisUnitTest.java

@@ -3,6 +3,8 @@ package cn.iocoder.yudao.module.pay.test;
 import cn.iocoder.yudao.framework.datasource.config.YudaoDataSourceAutoConfiguration;
 import cn.iocoder.yudao.framework.mybatis.config.YudaoMybatisAutoConfiguration;
 import cn.iocoder.yudao.framework.redis.config.YudaoRedisAutoConfiguration;
+import cn.iocoder.yudao.framework.test.config.RedisTestConfiguration;
+import cn.iocoder.yudao.framework.test.config.SqlInitializationTestConfiguration;
 import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure;
 import com.baomidou.mybatisplus.autoconfigure.MybatisPlusAutoConfiguration;
 import org.redisson.spring.starter.RedissonAutoConfiguration;
@@ -23,7 +25,6 @@ import org.springframework.test.context.jdbc.Sql;
  */
 @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE, classes = BaseDbAndRedisUnitTest.Application.class)
 @ActiveProfiles("unit-test") // 设置使用 application-unit-test 配置文件
-@Sql(scripts = "/sql/create_tables.sql", executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD) // 每个单元测试结束前,创建表
 @Sql(scripts = "/sql/clean.sql", executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD) // 每个单元测试结束后,清理 DB
 public class BaseDbAndRedisUnitTest {
 
@@ -33,9 +34,11 @@ public class BaseDbAndRedisUnitTest {
             DataSourceAutoConfiguration.class, // Spring DB 自动配置类
             DataSourceTransactionManagerAutoConfiguration.class, // Spring 事务自动配置类
             DruidDataSourceAutoConfigure.class, // Druid 自动配置类
+            SqlInitializationTestConfiguration.class, // SQL 初始化
             // MyBatis 配置类
             YudaoMybatisAutoConfiguration.class, // 自己的 MyBatis 配置类
             MybatisPlusAutoConfiguration.class, // MyBatis 的自动配置类
+
             // Redis 配置类
             RedisTestConfiguration.class, // Redis 测试配置类,用于启动 RedisServer
             RedisAutoConfiguration.class, // Spring Redis 自动配置类

+ 2 - 1
yudao-module-pay/yudao-module-pay-impl/src/test/java/cn/iocoder/yudao/module/pay/test/BaseDbUnitTest.java

@@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.pay.test;
 
 import cn.iocoder.yudao.framework.datasource.config.YudaoDataSourceAutoConfiguration;
 import cn.iocoder.yudao.framework.mybatis.config.YudaoMybatisAutoConfiguration;
+import cn.iocoder.yudao.framework.test.config.SqlInitializationTestConfiguration;
 import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure;
 import com.baomidou.mybatisplus.autoconfigure.MybatisPlusAutoConfiguration;
 import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
@@ -20,7 +21,6 @@ import org.springframework.test.context.jdbc.Sql;
  */
 @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE, classes = BaseDbUnitTest.Application.class)
 @ActiveProfiles("unit-test") // 设置使用 application-unit-test 配置文件
-@Sql(scripts = "/sql/create_tables.sql", executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD) // 每个单元测试结束前,创建表
 @Sql(scripts = "/sql/clean.sql", executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD) // 每个单元测试结束后,清理 DB
 public class BaseDbUnitTest {
 
@@ -30,6 +30,7 @@ public class BaseDbUnitTest {
             DataSourceAutoConfiguration.class, // Spring DB 自动配置类
             DataSourceTransactionManagerAutoConfiguration.class, // Spring 事务自动配置类
             DruidDataSourceAutoConfigure.class, // Druid 自动配置类
+            SqlInitializationTestConfiguration.class, // SQL 初始化
             // MyBatis 配置类
             YudaoMybatisAutoConfiguration.class, // 自己的 MyBatis 配置类
             MybatisPlusAutoConfiguration.class, // MyBatis 的自动配置类

+ 0 - 30
yudao-module-pay/yudao-module-pay-impl/src/test/java/cn/iocoder/yudao/module/pay/test/RedisTestConfiguration.java

@@ -1,30 +0,0 @@
-package cn.iocoder.yudao.module.pay.test;
-
-import com.github.fppt.jedismock.RedisServer;
-import org.springframework.boot.autoconfigure.data.redis.RedisProperties;
-import org.springframework.boot.context.properties.EnableConfigurationProperties;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.context.annotation.Lazy;
-
-import java.io.IOException;
-
-@Configuration(proxyBeanMethods = false)
-@Lazy(false) // 禁止延迟加载
-@EnableConfigurationProperties(RedisProperties.class)
-public class RedisTestConfiguration {
-
-    /**
-     * 创建模拟的 Redis Server 服务器
-     */
-    @Bean
-    public RedisServer redisServer(RedisProperties properties) throws IOException {
-        RedisServer redisServer = new RedisServer(properties.getPort());
-        // TODO 芋艿:一次执行多个单元测试时,貌似创建多个 spring 容器,导致不进行 stop。这样,就导致端口被占用,无法启动。。。
-        try {
-            redisServer.start();
-        } catch (Exception ignore) {}
-        return redisServer;
-    }
-
-}

+ 3 - 0
yudao-module-pay/yudao-module-pay-impl/src/test/resources/application-unit-test.yaml

@@ -16,6 +16,9 @@ spring:
     druid:
       async-init: true # 单元测试,异步初始化 Druid 连接池,提升启动速度
       initial-size: 1 # 单元测试,配置为 1,提升启动速度
+  sql:
+    init:
+      schema-locations: classpath:/sql/create_tables.sql
 
   # Redis 配置。Redisson 默认的配置足够使用,一般不需要进行调优
   redis:

+ 1 - 5
yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/MenuController.java

@@ -1,6 +1,5 @@
 package cn.iocoder.yudao.module.system.controller.admin.permission;
 
-import cn.hutool.core.collection.CollUtil;
 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
 import cn.iocoder.yudao.module.system.controller.admin.permission.vo.menu.*;
@@ -74,12 +73,9 @@ public class MenuController {
         // 获得菜单列表,只要开启状态的
         MenuListReqVO reqVO = new MenuListReqVO();
         reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus());
-        List<MenuDO> list = menuService.getMenus(reqVO);
+        List<MenuDO> list = menuService.getTenantMenus(reqVO);
         // 排序后,返回给前端
         list.sort(Comparator.comparing(MenuDO::getSort));
-
-        // 开启多租户的情况下,需要过滤掉未开通的菜单
-        tenantService.handleTenantMenu(menuIds -> list.removeIf(menu -> !CollUtil.contains(menuIds, menu.getId())));
         return success(MenuConvert.INSTANCE.convertList02(list));
     }
 

+ 9 - 0
yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/service/permission/MenuService.java

@@ -49,6 +49,15 @@ public interface MenuService {
      */
     List<MenuDO> getMenus();
 
+    /**
+     * 基于租户,筛选菜单列表
+     * 注意,如果是系统租户,返回的还是全菜单
+     *
+     * @param reqVO 筛选条件请求 VO
+     * @return 菜单列表
+     */
+    List<MenuDO> getTenantMenus(MenuListReqVO reqVO);
+
     /**
      * 筛选菜单列表
      *

+ 11 - 0
yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/service/permission/MenuServiceImpl.java

@@ -12,6 +12,7 @@ import cn.iocoder.yudao.module.system.dal.mysql.permission.MenuMapper;
 import cn.iocoder.yudao.module.system.enums.permission.MenuIdEnum;
 import cn.iocoder.yudao.module.system.enums.permission.MenuTypeEnum;
 import cn.iocoder.yudao.module.system.mq.producer.permission.MenuProducer;
+import cn.iocoder.yudao.module.system.service.tenant.TenantService;
 import com.google.common.annotations.VisibleForTesting;
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.ImmutableMultimap;
@@ -69,6 +70,8 @@ public class MenuServiceImpl implements MenuService {
     private MenuMapper menuMapper;
     @Resource
     private PermissionService permissionService;
+    @Resource
+    private TenantService tenantService;
 
     @Resource
     private MenuProducer menuProducer;
@@ -193,6 +196,14 @@ public class MenuServiceImpl implements MenuService {
         return menuMapper.selectList();
     }
 
+    @Override
+    public List<MenuDO> getTenantMenus(MenuListReqVO reqVO) {
+        List<MenuDO> menus = getMenus(reqVO);
+        // 开启多租户的情况下,需要过滤掉未开通的菜单
+        tenantService.handleTenantMenu(menuIds -> menus.removeIf(menu -> !CollUtil.contains(menuIds, menu.getId())));
+        return menus;
+    }
+
     @Override
     public List<MenuDO> getMenus(MenuListReqVO reqVO) {
         return menuMapper.selectList(reqVO);

+ 4 - 0
yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/service/permission/RoleServiceImpl.java

@@ -19,6 +19,7 @@ import cn.iocoder.yudao.module.system.enums.permission.RoleCodeEnum;
 import cn.iocoder.yudao.module.system.enums.permission.RoleTypeEnum;
 import cn.iocoder.yudao.module.system.mq.producer.permission.RoleProducer;
 import com.google.common.annotations.VisibleForTesting;
+import lombok.Getter;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.context.annotation.Lazy;
 import org.springframework.lang.Nullable;
@@ -58,10 +59,12 @@ public class RoleServiceImpl implements RoleService {
      *
      * 这里声明 volatile 修饰的原因是,每次刷新时,直接修改指向
      */
+    @Getter
     private volatile Map<Long, RoleDO> roleCache;
     /**
      * 缓存角色的最大更新时间,用于后续的增量轮询,判断是否有更新
      */
+    @Getter
     private volatile Date maxUpdateTime;
 
     @Resource
@@ -144,6 +147,7 @@ public class RoleServiceImpl implements RoleService {
         checkUpdateRole(reqVO.getId());
         // 校验角色的唯一字段是否重复
         checkDuplicateRole(reqVO.getName(), reqVO.getCode(), reqVO.getId());
+
         // 更新到数据库
         RoleDO updateObject = RoleConvert.INSTANCE.convert(reqVO);
         roleMapper.updateById(updateObject);

+ 75 - 45
yudao-module-system/yudao-module-system-impl/src/test/java/cn/iocoder/yudao/module/system/service/permission/MenuServiceTest.java

@@ -3,6 +3,8 @@ package cn.iocoder.yudao.module.system.service.permission;
 import cn.hutool.core.bean.BeanUtil;
 import cn.hutool.core.lang.Assert;
 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
+import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
+import cn.iocoder.yudao.framework.common.util.spring.SpringAopUtils;
 import cn.iocoder.yudao.module.system.controller.admin.permission.vo.menu.MenuCreateReqVO;
 import cn.iocoder.yudao.module.system.controller.admin.permission.vo.menu.MenuListReqVO;
 import cn.iocoder.yudao.module.system.controller.admin.permission.vo.menu.MenuUpdateReqVO;
@@ -10,8 +12,7 @@ import cn.iocoder.yudao.module.system.dal.dataobject.permission.MenuDO;
 import cn.iocoder.yudao.module.system.dal.mysql.permission.MenuMapper;
 import cn.iocoder.yudao.module.system.enums.permission.MenuTypeEnum;
 import cn.iocoder.yudao.module.system.mq.producer.permission.MenuProducer;
-import cn.iocoder.yudao.framework.common.util.spring.SpringAopUtils;
-import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
+import cn.iocoder.yudao.module.system.service.tenant.TenantService;
 import cn.iocoder.yudao.module.system.test.BaseDbUnitTest;
 import com.google.common.collect.Multimap;
 import org.junit.jupiter.api.Test;
@@ -21,28 +22,33 @@ import org.springframework.context.annotation.Import;
 import javax.annotation.Resource;
 import java.util.*;
 
-import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*;
+import static cn.iocoder.yudao.framework.common.util.collection.SetUtils.asSet;
 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.*;
+import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*;
 import static org.junit.jupiter.api.Assertions.*;
+import static org.mockito.ArgumentMatchers.argThat;
+import static org.mockito.Mockito.doNothing;
 import static org.mockito.Mockito.verify;
 
+// TODO @芋艿:单测的代码质量可以提升下
 @Import(MenuServiceImpl.class)
 public class MenuServiceTest extends BaseDbUnitTest {
 
     @Resource
-    private MenuServiceImpl sysMenuService;
-
-    @MockBean
-    private PermissionService sysPermissionService;
-
-    @MockBean
-    private MenuProducer sysMenuProducer;
+    private MenuServiceImpl menuService;
 
     @Resource
     private MenuMapper menuMapper;
 
+    @MockBean
+    private PermissionService permissionService;
+    @MockBean
+    private MenuProducer menuProducer;
+    @MockBean
+    private TenantService tenantService;
+
     @Test
     public void testInitLocalCache_success() throws Exception {
         MenuDO menuDO1 = createMenuDO(MenuTypeEnum.MENU, "xxxx", 0L);
@@ -51,10 +57,10 @@ public class MenuServiceTest extends BaseDbUnitTest {
         menuMapper.insert(menuDO2);
 
         // 调用
-        sysMenuService.initLocalCache();
+        menuService.initLocalCache();
 
         // 获取代理对象
-        MenuServiceImpl target = (MenuServiceImpl) SpringAopUtils.getTarget(sysMenuService);
+        MenuServiceImpl target = (MenuServiceImpl) SpringAopUtils.getTarget(menuService);
 
         Map<Long, MenuDO> menuCache =
                 (Map<Long, MenuDO>) BeanUtil.getFieldValue(target, "menuCache");
@@ -86,7 +92,7 @@ public class MenuServiceTest extends BaseDbUnitTest {
             o.setType(MenuTypeEnum.MENU.getType());
             o.setStatus(randomCommonStatus());
         });
-        Long menuId = sysMenuService.createMenu(vo);
+        Long menuId = menuService.createMenu(vo);
 
         //断言
         assertNotNull(menuId);
@@ -94,7 +100,7 @@ public class MenuServiceTest extends BaseDbUnitTest {
         MenuDO ret = menuMapper.selectById(menuId);
         assertPojoEquals(vo, ret);
         // 校验调用
-        verify(sysMenuProducer).sendMenuRefreshMessage();
+        verify(menuProducer).sendMenuRefreshMessage();
     }
 
     @Test
@@ -112,14 +118,14 @@ public class MenuServiceTest extends BaseDbUnitTest {
             o.setStatus(randomCommonStatus());
             o.setName("pppppp"); //修改名字
         });
-        sysMenuService.updateMenu(vo);
+        menuService.updateMenu(vo);
 
         //断言
         // 校验记录的属性是否正确
         MenuDO ret = menuMapper.selectById(sonId);
         assertPojoEquals(vo, ret);
         // 校验调用
-        verify(sysMenuProducer).sendMenuRefreshMessage();
+        verify(menuProducer).sendMenuRefreshMessage();
     }
 
     @Test
@@ -135,7 +141,7 @@ public class MenuServiceTest extends BaseDbUnitTest {
             o.setStatus(randomCommonStatus());
         });
         //断言
-        assertServiceException(() -> sysMenuService.updateMenu(vo), MENU_NOT_EXISTS);
+        assertServiceException(() -> menuService.updateMenu(vo), MENU_NOT_EXISTS);
     }
 
     @Test
@@ -144,20 +150,20 @@ public class MenuServiceTest extends BaseDbUnitTest {
         Long sonId = sonMenuDO.getId();
 
         // 调用
-        sysMenuService.deleteMenu(sonId);
+        menuService.deleteMenu(sonId);
 
         // 断言
         MenuDO menuDO = menuMapper.selectById(sonId);
         assertNull(menuDO);
-        verify(sysPermissionService).processMenuDeleted(sonId);
-        verify(sysMenuProducer).sendMenuRefreshMessage();
+        verify(permissionService).processMenuDeleted(sonId);
+        verify(menuProducer).sendMenuRefreshMessage();
     }
 
     @Test
     public void testDeleteMenu_menuNotExist() {
         Long sonId = 99999L;
 
-        assertServiceException(() -> sysMenuService.deleteMenu(sonId), MENU_NOT_EXISTS);
+        assertServiceException(() -> menuService.deleteMenu(sonId), MENU_NOT_EXISTS);
     }
 
     @Test
@@ -165,26 +171,50 @@ public class MenuServiceTest extends BaseDbUnitTest {
         MenuDO sonMenu = initParentAndSonMenuDO();
         Long parentId = sonMenu.getParentId();
 
-        assertServiceException(() -> sysMenuService.deleteMenu(parentId), MENU_EXISTS_CHILDREN);
+        assertServiceException(() -> menuService.deleteMenu(parentId), MENU_EXISTS_CHILDREN);
     }
 
     @Test
-    public void testGetMenus_success() {
-        Map<Long, MenuDO> idMenuMap = new HashMap<>();
-        MenuDO menuDO = createMenuDO(MenuTypeEnum.MENU, "parent", 0L);
-        menuMapper.insert(menuDO);
-        idMenuMap.put(menuDO.getId(), menuDO);
-
-        MenuDO sonMenu = createMenuDO(MenuTypeEnum.MENU, "son", menuDO.getId());
-        menuMapper.insert(sonMenu);
-        idMenuMap.put(sonMenu.getId(), sonMenu);
+    public void testGetMenus() {
+        // mock 数据
+        MenuDO menu100 = randomPojo(MenuDO.class, o -> o.setId(100L).setStatus(CommonStatusEnum.ENABLE.getStatus()));
+        menuMapper.insert(menu100);
+        MenuDO menu101 = randomPojo(MenuDO.class, o -> o.setId(101L).setStatus(CommonStatusEnum.DISABLE.getStatus()));
+        menuMapper.insert(menu101);
+        // 准备参数
+        MenuListReqVO reqVO = new MenuListReqVO().setStatus(CommonStatusEnum.ENABLE.getStatus());
 
         // 调用
-        List<MenuDO> menuDOS = sysMenuService.getMenus();
+        List<MenuDO> result = menuService.getMenus(reqVO);
+        // 断言
+        assertEquals(1, result.size());
+        assertPojoEquals(menu100, result.get(0));
+    }
+
+    @Test
+    public void testTenantMenus() {
+        // mock 数据
+        MenuDO menu100 = randomPojo(MenuDO.class, o -> o.setId(100L).setStatus(CommonStatusEnum.ENABLE.getStatus()));
+        menuMapper.insert(menu100);
+        MenuDO menu101 = randomPojo(MenuDO.class, o -> o.setId(101L).setStatus(CommonStatusEnum.DISABLE.getStatus()));
+        menuMapper.insert(menu101);
+        MenuDO menu102 = randomPojo(MenuDO.class, o -> o.setId(102L).setStatus(CommonStatusEnum.ENABLE.getStatus()));
+        menuMapper.insert(menu102);
+        // mock 过滤菜单
+        // mock 账户额度充足
+        Set<Long> menuIds = asSet(100L, 101L);
+        doNothing().when(tenantService).handleTenantMenu(argThat(handler -> {
+            handler.handle(menuIds);
+            return true;
+        }));
+        // 准备参数
+        MenuListReqVO reqVO = new MenuListReqVO().setStatus(CommonStatusEnum.ENABLE.getStatus());
 
+        // 调用
+        List<MenuDO> result = menuService.getTenantMenus(reqVO);
         // 断言
-        assertEquals(menuDOS.size(), idMenuMap.size());
-        menuDOS.forEach(m -> assertPojoEquals(idMenuMap.get(m.getId()), m));
+        assertEquals(1, result.size());
+        assertPojoEquals(menu100, result.get(0));
     }
 
     @Test
@@ -213,7 +243,7 @@ public class MenuServiceTest extends BaseDbUnitTest {
         MenuListReqVO reqVO = new MenuListReqVO();
         reqVO.setStatus(1);
         reqVO.setName("name");
-        List<MenuDO> menuDOS = sysMenuService.getMenus(reqVO);
+        List<MenuDO> menuDOS = menuService.getMenus(reqVO);
 
         // 断言
         assertEquals(menuDOS.size(), idMenuMap.size());
@@ -224,7 +254,7 @@ public class MenuServiceTest extends BaseDbUnitTest {
     public void testListMenusFromCache_success() throws Exception {
         Map<Long, MenuDO> mockCacheMap = new HashMap<>();
         // 获取代理对象
-        MenuServiceImpl target = (MenuServiceImpl) SpringAopUtils.getTarget(sysMenuService);
+        MenuServiceImpl target = (MenuServiceImpl) SpringAopUtils.getTarget(menuService);
         BeanUtil.setFieldValue(target, "menuCache", mockCacheMap);
 
         Map<Long, MenuDO> idMenuMap = new HashMap<>();
@@ -243,7 +273,7 @@ public class MenuServiceTest extends BaseDbUnitTest {
         menuDO = createMenuDO(4L, MenuTypeEnum.MENU, "name", 0L, 2);
         mockCacheMap.put(menuDO.getId(), menuDO);
 
-        List<MenuDO> menuDOS = sysMenuService.getMenuListFromCache(Collections.singletonList(MenuTypeEnum.MENU.getType()),
+        List<MenuDO> menuDOS = menuService.getMenuListFromCache(Collections.singletonList(MenuTypeEnum.MENU.getType()),
                 Collections.singletonList(CommonStatusEnum.DISABLE.getStatus()));
         assertEquals(menuDOS.size(), idMenuMap.size());
         menuDOS.forEach(m -> assertPojoEquals(idMenuMap.get(m.getId()), m));
@@ -253,7 +283,7 @@ public class MenuServiceTest extends BaseDbUnitTest {
     public void testListMenusFromCache2_success() throws Exception {
         Map<Long, MenuDO> mockCacheMap = new HashMap<>();
         // 获取代理对象
-        MenuServiceImpl target = (MenuServiceImpl) SpringAopUtils.getTarget(sysMenuService);
+        MenuServiceImpl target = (MenuServiceImpl) SpringAopUtils.getTarget(menuService);
         BeanUtil.setFieldValue(target, "menuCache", mockCacheMap);
 
         Map<Long, MenuDO> idMenuMap = new HashMap<>();
@@ -270,7 +300,7 @@ public class MenuServiceTest extends BaseDbUnitTest {
         menuDO = createMenuDO(4L, MenuTypeEnum.MENU, "name", 0L, 2);
         mockCacheMap.put(menuDO.getId(), menuDO);
 
-        List<MenuDO> menuDOS = sysMenuService.getMenuListFromCache(Collections.singletonList(1L),
+        List<MenuDO> menuDOS = menuService.getMenuListFromCache(Collections.singletonList(1L),
                 Collections.singletonList(MenuTypeEnum.MENU.getType()), Collections.singletonList(1));
         assertEquals(menuDOS.size(), idMenuMap.size());
         menuDOS.forEach(menu -> assertPojoEquals(idMenuMap.get(menu.getId()), menu));
@@ -282,17 +312,17 @@ public class MenuServiceTest extends BaseDbUnitTest {
         menuMapper.insert(menuDO);
         Long parentId = menuDO.getId();
 
-        sysMenuService.checkParentResource(parentId, null);
+        menuService.checkParentResource(parentId, null);
     }
 
     @Test
     public void testCheckParentResource_canNotSetSelfToBeParent() {
-        assertServiceException(() -> sysMenuService.checkParentResource(1L, 1L), MENU_PARENT_ERROR);
+        assertServiceException(() -> menuService.checkParentResource(1L, 1L), MENU_PARENT_ERROR);
     }
 
     @Test
     public void testCheckParentResource_parentNotExist() {
-        assertServiceException(() -> sysMenuService.checkParentResource(randomLongId(), null), MENU_PARENT_NOT_EXISTS);
+        assertServiceException(() -> menuService.checkParentResource(randomLongId(), null), MENU_PARENT_NOT_EXISTS);
     }
 
     @Test
@@ -301,7 +331,7 @@ public class MenuServiceTest extends BaseDbUnitTest {
         menuMapper.insert(menuDO);
         Long parentId = menuDO.getId();
 
-        assertServiceException(() -> sysMenuService.checkParentResource(parentId, null), MENU_PARENT_NOT_DIR_OR_MENU);
+        assertServiceException(() -> menuService.checkParentResource(parentId, null), MENU_PARENT_NOT_DIR_OR_MENU);
     }
 
     @Test
@@ -312,7 +342,7 @@ public class MenuServiceTest extends BaseDbUnitTest {
         Long otherSonMenuId = randomLongId();
         String otherSonMenuName = randomString();
 
-        sysMenuService.checkResource(parentId, otherSonMenuName, otherSonMenuId);
+        menuService.checkResource(parentId, otherSonMenuName, otherSonMenuId);
     }
 
     @Test
@@ -323,7 +353,7 @@ public class MenuServiceTest extends BaseDbUnitTest {
         Long otherSonMenuId=randomLongId();
         String otherSonMenuName=sonMenu.getName(); //相同名称
 
-        assertServiceException(() -> sysMenuService.checkResource(parentId, otherSonMenuName, otherSonMenuId), MENU_NAME_DUPLICATE);
+        assertServiceException(() -> menuService.checkResource(parentId, otherSonMenuName, otherSonMenuId), MENU_NAME_DUPLICATE);
     }
 
     /**

+ 0 - 1
yudao-module-system/yudao-module-system-impl/src/test/java/cn/iocoder/yudao/module/system/service/permission/PermissionServiceTest.java

@@ -47,7 +47,6 @@ public class PermissionServiceTest extends BaseDbUnitTest {
     private MenuService menuService;
     @MockBean
     private DeptService deptService;
-
     @MockBean
     private PermissionProducer permissionProducer;
 

+ 49 - 50
yudao-module-system/yudao-module-system-impl/src/test/java/cn/iocoder/yudao/module/system/service/permission/RoleServiceTest.java

@@ -1,6 +1,6 @@
 package cn.iocoder.yudao.module.system.service.permission;
 
-import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.util.RandomUtil;
 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.security.core.enums.DataScopeEnum;
@@ -11,7 +11,6 @@ import cn.iocoder.yudao.module.system.dal.dataobject.permission.RoleDO;
 import cn.iocoder.yudao.module.system.dal.mysql.permission.RoleMapper;
 import cn.iocoder.yudao.module.system.enums.permission.RoleTypeEnum;
 import cn.iocoder.yudao.module.system.mq.producer.permission.RoleProducer;
-import cn.iocoder.yudao.framework.common.util.spring.SpringAopUtils;
 import cn.iocoder.yudao.module.system.test.BaseDbUnitTest;
 import org.junit.jupiter.api.Test;
 import org.springframework.boot.test.mock.mockito.MockBean;
@@ -21,71 +20,67 @@ import javax.annotation.Resource;
 import java.util.*;
 import java.util.stream.Collectors;
 
-import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*;
+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.common.util.object.ObjectUtils.max;
 import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*;
+import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*;
 import static org.junit.jupiter.api.Assertions.*;
 import static org.mockito.Mockito.verify;
 
+// TODO @芋艿:单测的代码质量可以提升下
 @Import(RoleServiceImpl.class)
 public class RoleServiceTest extends BaseDbUnitTest {
 
     @Resource
-    private RoleServiceImpl sysRoleService;
+    private RoleServiceImpl roleService;
 
     @Resource
     private RoleMapper roleMapper;
 
     @MockBean
-    private PermissionService sysPermissionService;
-
+    private PermissionService permissionService;
     @MockBean
-    private RoleProducer sysRoleProducer;
+    private RoleProducer roleProducer;
 
     @Test
-    public void testInitLocalCache_success() throws Exception {
-        RoleDO roleDO1 = createRoleDO("role1", RoleTypeEnum.CUSTOM, DataScopeEnum.ALL);
+    public void testInitLocalCache() {
+        RoleDO roleDO1 = randomRole();
         roleMapper.insert(roleDO1);
-        RoleDO roleDO2 = createRoleDO("role2", RoleTypeEnum.CUSTOM, DataScopeEnum.ALL);
+        RoleDO roleDO2 = randomRole();
         roleMapper.insert(roleDO2);
 
-        //调用
-        sysRoleService.initLocalCache();
-
-        //断言
-        //获取代理对象
-        RoleServiceImpl target = (RoleServiceImpl) SpringAopUtils.getTarget(sysRoleService);
-
-        Map<Long, RoleDO> roleCache = (Map<Long, RoleDO>) BeanUtil.getFieldValue(target, "roleCache");
+        // 调用
+        roleService.initLocalCache();
+        // 断言 roleCache 缓存
+        Map<Long, RoleDO> roleCache = roleService.getRoleCache();
         assertPojoEquals(roleDO1, roleCache.get(roleDO1.getId()));
         assertPojoEquals(roleDO2, roleCache.get(roleDO2.getId()));
-
-        Date maxUpdateTime = (Date) BeanUtil.getFieldValue(target, "maxUpdateTime");
-        assertEquals(max(roleDO1.getUpdateTime(), roleDO2.getUpdateTime()), maxUpdateTime);
+        // 断言 maxUpdateTime 缓存
+        assertEquals(max(roleDO1.getUpdateTime(), roleDO2.getUpdateTime()), roleService.getMaxUpdateTime());
     }
 
     @Test
     public void testCreateRole_success() {
-        RoleCreateReqVO reqVO = randomPojo(RoleCreateReqVO.class, o -> {
-            o.setCode("role_code");
-            o.setName("role_name");
-            o.setRemark("remark");
-            o.setSort(1);
-        });
-        Long roleId = sysRoleService.createRole(reqVO, null);
+        // 准备参数
+        RoleCreateReqVO reqVO = randomPojo(RoleCreateReqVO.class);
 
-        //断言
+        // 调用
+        Long roleId = roleService.createRole(reqVO, null);
+        // 断言
         assertNotNull(roleId);
         RoleDO roleDO = roleMapper.selectById(roleId);
         assertPojoEquals(reqVO, roleDO);
-
-        verify(sysRoleProducer).sendRoleRefreshMessage();
+        assertEquals(RoleTypeEnum.CUSTOM.getType(), roleDO.getType());
+        assertEquals(CommonStatusEnum.ENABLE.getStatus(), roleDO.getStatus());
+        assertEquals(DataScopeEnum.ALL.getScope(), roleDO.getDataScope());
+        // verify 发送刷新消息
+        verify(roleProducer).sendRoleRefreshMessage();
     }
 
     @Test
     public void testUpdateRole_success() {
+        // mock 数据
         RoleDO roleDO = createRoleDO("role_name", RoleTypeEnum.CUSTOM, DataScopeEnum.ALL);
         roleMapper.insert(roleDO);
         Long roleId = roleDO.getId();
@@ -97,13 +92,13 @@ public class RoleServiceTest extends BaseDbUnitTest {
             o.setName("update_name");
             o.setSort(999);
         });
-        sysRoleService.updateRole(reqVO);
+        roleService.updateRole(reqVO);
 
         //断言
         RoleDO newRoleDO = roleMapper.selectById(roleId);
         assertPojoEquals(reqVO, newRoleDO);
 
-        verify(sysRoleProducer).sendRoleRefreshMessage();
+        verify(roleProducer).sendRoleRefreshMessage();
     }
 
     @Test
@@ -113,13 +108,13 @@ public class RoleServiceTest extends BaseDbUnitTest {
         Long roleId = roleDO.getId();
 
         //调用
-        sysRoleService.updateRoleStatus(roleId, CommonStatusEnum.DISABLE.getStatus());
+        roleService.updateRoleStatus(roleId, CommonStatusEnum.DISABLE.getStatus());
 
         //断言
         RoleDO newRoleDO = roleMapper.selectById(roleId);
         assertEquals(CommonStatusEnum.DISABLE.getStatus(), newRoleDO.getStatus());
 
-        verify(sysRoleProducer).sendRoleRefreshMessage();
+        verify(roleProducer).sendRoleRefreshMessage();
     }
 
     @Test
@@ -130,7 +125,7 @@ public class RoleServiceTest extends BaseDbUnitTest {
 
         //调用
         Set<Long> deptIdSet = Arrays.asList(1L, 2L, 3L, 4L, 5L).stream().collect(Collectors.toSet());
-        sysRoleService.updateRoleDataScope(roleId, DataScopeEnum.DEPT_CUSTOM.getScope(), deptIdSet);
+        roleService.updateRoleDataScope(roleId, DataScopeEnum.DEPT_CUSTOM.getScope(), deptIdSet);
 
         //断言
         RoleDO newRoleDO = roleMapper.selectById(roleId);
@@ -140,7 +135,7 @@ public class RoleServiceTest extends BaseDbUnitTest {
         assertTrue(deptIdSet.size() == newDeptIdSet.size());
         deptIdSet.stream().forEach(d -> assertTrue(newDeptIdSet.contains(d)));
 
-        verify(sysRoleProducer).sendRoleRefreshMessage();
+        verify(roleProducer).sendRoleRefreshMessage();
     }
 
     @Test
@@ -150,13 +145,13 @@ public class RoleServiceTest extends BaseDbUnitTest {
         Long roleId = roleDO.getId();
 
         //调用
-        sysRoleService.deleteRole(roleId);
+        roleService.deleteRole(roleId);
 
         //断言
         RoleDO newRoleDO = roleMapper.selectById(roleId);
         assertNull(newRoleDO);
 
-        verify(sysRoleProducer).sendRoleRefreshMessage();
+        verify(roleProducer).sendRoleRefreshMessage();
     }
 
     @Test
@@ -176,7 +171,7 @@ public class RoleServiceTest extends BaseDbUnitTest {
         roleMapper.insert(roleDO3);
 
         //调用
-        List<RoleDO> roles = sysRoleService.getRoles(Arrays.asList(1));
+        List<RoleDO> roles = roleService.getRoles(Arrays.asList(1));
 
         //断言
         assertEquals(2, roles.size());
@@ -212,14 +207,14 @@ public class RoleServiceTest extends BaseDbUnitTest {
             o.setBeginTime(null);
             o.setEndTime(null);
         });
-        PageResult<RoleDO> result = sysRoleService.getRolePage(reqVO);
+        PageResult<RoleDO> result = roleService.getRolePage(reqVO);
         assertEquals(2, result.getTotal());
         result.getList().stream().forEach(r -> assertPojoEquals(idRoleMap.get(r.getId()), r));
     }
 
     @Test
     public void testCheckDuplicateRole_success() {
-        sysRoleService.checkDuplicateRole(randomString(), randomString(), null);
+        roleService.checkDuplicateRole(randomString(), randomString(), null);
     }
 
     @Test
@@ -229,7 +224,7 @@ public class RoleServiceTest extends BaseDbUnitTest {
 
         String duplicateName = "role_name";
 
-        assertServiceException(() -> sysRoleService.checkDuplicateRole(duplicateName, randomString(), null), ROLE_NAME_DUPLICATE, duplicateName);
+        assertServiceException(() -> roleService.checkDuplicateRole(duplicateName, randomString(), null), ROLE_NAME_DUPLICATE, duplicateName);
     }
 
     @Test
@@ -246,7 +241,7 @@ public class RoleServiceTest extends BaseDbUnitTest {
         String randomName = randomString();
         String duplicateCode = "code";
 
-        assertServiceException(() -> sysRoleService.checkDuplicateRole(randomName, duplicateCode, null), ROLE_CODE_DUPLICATE, duplicateCode);
+        assertServiceException(() -> roleService.checkDuplicateRole(randomName, duplicateCode, null), ROLE_CODE_DUPLICATE, duplicateCode);
     }
 
     @Test
@@ -255,12 +250,12 @@ public class RoleServiceTest extends BaseDbUnitTest {
         roleMapper.insert(roleDO);
         Long roleId = roleDO.getId();
 
-        sysRoleService.checkUpdateRole(roleId);
+        roleService.checkUpdateRole(roleId);
     }
 
     @Test
     public void testCheckUpdateRole_roleIdNotExist() {
-        assertServiceException(() -> sysRoleService.checkUpdateRole(randomLongId()), ROLE_NOT_EXISTS);
+        assertServiceException(() -> roleService.checkUpdateRole(randomLongId()), ROLE_NOT_EXISTS);
     }
 
     @Test
@@ -269,7 +264,7 @@ public class RoleServiceTest extends BaseDbUnitTest {
         roleMapper.insert(roleDO);
         Long roleId = roleDO.getId();
 
-        assertServiceException(() -> sysRoleService.checkUpdateRole(roleId), ROLE_CAN_NOT_UPDATE_SYSTEM_TYPE_ROLE);
+        assertServiceException(() -> roleService.checkUpdateRole(roleId), ROLE_CAN_NOT_UPDATE_SYSTEM_TYPE_ROLE);
     }
 
     private RoleDO createRoleDO(String name, RoleTypeEnum typeEnum, DataScopeEnum scopeEnum, Integer status) {
@@ -285,7 +280,7 @@ public class RoleServiceTest extends BaseDbUnitTest {
     }
 
     private RoleDO createRoleDO(Long id, String name, RoleTypeEnum typeEnum, DataScopeEnum scopeEnum, Integer status, String code) {
-        RoleDO roleDO = randomPojo(RoleDO.class, o -> {
+        return randomPojo(RoleDO.class, o -> {
             o.setId(id);
             o.setName(name);
             o.setType(typeEnum.getType());
@@ -293,7 +288,11 @@ public class RoleServiceTest extends BaseDbUnitTest {
             o.setDataScope(scopeEnum.getScope());
             o.setCode(code);
         });
-        return roleDO;
+    }
+
+    private RoleDO randomRole() {
+        return randomPojo(RoleDO.class,
+                o -> o.setDataScope(RandomUtil.randomEle(DataScopeEnum.values()).getScope()));
     }
 
 }

+ 25 - 1
yudao-module-system/yudao-module-system-impl/src/test/java/cn/iocoder/yudao/module/system/service/user/UserServiceImplTest.java

@@ -13,12 +13,14 @@ import cn.iocoder.yudao.module.system.controller.admin.user.vo.profile.UserProfi
 import cn.iocoder.yudao.module.system.controller.admin.user.vo.user.*;
 import cn.iocoder.yudao.module.system.dal.dataobject.dept.DeptDO;
 import cn.iocoder.yudao.module.system.dal.dataobject.dept.PostDO;
+import cn.iocoder.yudao.module.system.dal.dataobject.tenant.TenantDO;
 import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
 import cn.iocoder.yudao.module.system.dal.mysql.user.AdminUserMapper;
 import cn.iocoder.yudao.module.system.enums.common.SexEnum;
 import cn.iocoder.yudao.module.system.service.dept.DeptService;
 import cn.iocoder.yudao.module.system.service.dept.PostService;
 import cn.iocoder.yudao.module.system.service.permission.PermissionService;
+import cn.iocoder.yudao.module.system.service.tenant.TenantService;
 import cn.iocoder.yudao.module.system.test.BaseDbUnitTest;
 import org.junit.jupiter.api.Test;
 import org.mockito.stubbing.Answer;
@@ -55,7 +57,6 @@ public class UserServiceImplTest extends BaseDbUnitTest {
 
     @MockBean
     private DeptService deptService;
-
     @MockBean
     private PostService postService;
     @MockBean
@@ -63,6 +64,8 @@ public class UserServiceImplTest extends BaseDbUnitTest {
     @MockBean
     private PasswordEncoder passwordEncoder;
     @MockBean
+    private TenantService tenantService;
+    @MockBean
     private FileApi fileApi;
 
     @Test
@@ -72,6 +75,12 @@ public class UserServiceImplTest extends BaseDbUnitTest {
             o.setSex(RandomUtil.randomEle(SexEnum.values()).getSex());
             o.setMobile(randomString());
         });
+        // mock 账户额度充足
+        TenantDO tenant = randomPojo(TenantDO.class, o -> o.setAccountCount(1));
+        doNothing().when(tenantService).handleTenantInfo(argThat(handler -> {
+            handler.handle(tenant);
+            return true;
+        }));
         // mock deptService 的方法
         DeptDO dept = randomPojo(DeptDO.class, o -> {
             o.setId(reqVO.getDeptId());
@@ -97,6 +106,21 @@ public class UserServiceImplTest extends BaseDbUnitTest {
         assertEquals(CommonStatusEnum.ENABLE.getStatus(), user.getStatus());
     }
 
+    @Test
+    public void testCreatUser_max() {
+        // 准备参数
+        UserCreateReqVO reqVO = randomPojo(UserCreateReqVO.class);
+        // mock 账户额度不足
+        TenantDO tenant = randomPojo(TenantDO.class, o -> o.setAccountCount(-1));
+        doNothing().when(tenantService).handleTenantInfo(argThat(handler -> {
+            handler.handle(tenant);
+            return true;
+        }));
+
+        // 调用,并断言异常
+        assertServiceException(() -> userService.createUser(reqVO), USER_COUNT_MAX, -1);
+    }
+
     @Test
     public void testUpdateUser_success() {
         // mock 数据

+ 4 - 1
yudao-module-system/yudao-module-system-impl/src/test/resources/sql/create_tables.sql

@@ -49,6 +49,7 @@ CREATE TABLE IF NOT EXISTS "system_role" (
     "updater" varchar(64) DEFAULT '',
     "update_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
     "deleted" bit NOT NULL DEFAULT FALSE,
+    "tenant_id" bigint not null default  '0',
     PRIMARY KEY ("id")
 ) COMMENT '角色信息表';
 
@@ -61,6 +62,7 @@ CREATE TABLE IF NOT EXISTS "system_role_menu" (
     "updater" varchar(64) DEFAULT '',
     "update_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
     "deleted" bit NOT NULL DEFAULT FALSE,
+    "tenant_id" bigint not null default  '0',
     PRIMARY KEY ("id")
 ) COMMENT '角色和菜单关联表';
 
@@ -92,7 +94,8 @@ CREATE TABLE IF NOT EXISTS "system_user_role" (
      "updater" varchar(64) DEFAULT '',
      "update_time" timestamp DEFAULT NULL,
      "deleted" bit DEFAULT FALSE,
-     PRIMARY KEY ("id")
+    "tenant_id" bigint not null default  '0',
+    PRIMARY KEY ("id")
 ) COMMENT '用户和角色关联表';
 
 CREATE TABLE IF NOT EXISTS "system_dict_type" (

+ 2 - 1
yudao-module-tool/yudao-module-tool-impl/src/test/java/cn/iocoder/yudao/module/tool/test/BaseDbUnitTest.java

@@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.tool.test;
 
 import cn.iocoder.yudao.framework.datasource.config.YudaoDataSourceAutoConfiguration;
 import cn.iocoder.yudao.framework.mybatis.config.YudaoMybatisAutoConfiguration;
+import cn.iocoder.yudao.framework.test.config.SqlInitializationTestConfiguration;
 import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure;
 import com.baomidou.mybatisplus.autoconfigure.MybatisPlusAutoConfiguration;
 import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
@@ -20,7 +21,6 @@ import org.springframework.test.context.jdbc.Sql;
  */
 @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE, classes = BaseDbUnitTest.Application.class)
 @ActiveProfiles("unit-test") // 设置使用 application-unit-test 配置文件
-@Sql(scripts = "/sql/create_tables.sql", executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD) // 每个单元测试结束前,创建表
 @Sql(scripts = "/sql/clean.sql", executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD) // 每个单元测试结束后,清理 DB
 public class BaseDbUnitTest {
 
@@ -30,6 +30,7 @@ public class BaseDbUnitTest {
             DataSourceAutoConfiguration.class, // Spring DB 自动配置类
             DataSourceTransactionManagerAutoConfiguration.class, // Spring 事务自动配置类
             DruidDataSourceAutoConfigure.class, // Druid 自动配置类
+            SqlInitializationTestConfiguration.class, // SQL 初始化
             // MyBatis 配置类
             YudaoMybatisAutoConfiguration.class, // 自己的 MyBatis 配置类
             MybatisPlusAutoConfiguration.class, // MyBatis 的自动配置类

+ 3 - 0
yudao-module-tool/yudao-module-tool-impl/src/test/resources/application-unit-test.yaml

@@ -16,6 +16,9 @@ spring:
     druid:
       async-init: true # 单元测试,异步初始化 Druid 连接池,提升启动速度
       initial-size: 1 # 单元测试,配置为 1,提升启动速度
+  sql:
+    init:
+      schema-locations: classpath:/sql/create_tables.sql
 
   # Redis 配置。Redisson 默认的配置足够使用,一般不需要进行调优
   redis: