Pārlūkot izejas kodu

解决 spring.sql.init.schema-locations 不自动初始化,通过自定义的 SqlInitializationTestConfiguration 实现

YunaiV 3 gadi atpakaļ
vecāks
revīzija
c64bb81cae

+ 7 - 2
yudao-module-system/yudao-module-system-impl/src/test/java/cn/iocoder/yudao/module/system/test/RedisTestConfiguration.java → yudao-framework/yudao-spring-boot-starter-test/src/main/java/cn/iocoder/yudao/framework/test/config/RedisTestConfiguration.java

@@ -1,4 +1,4 @@
-package cn.iocoder.yudao.module.system.test;
+package cn.iocoder.yudao.framework.test.config;
 
 import com.github.fppt.jedismock.RedisServer;
 import org.springframework.boot.autoconfigure.data.redis.RedisProperties;
@@ -9,6 +9,11 @@ import org.springframework.context.annotation.Lazy;
 
 import java.io.IOException;
 
+/**
+ * Redis 测试 Configuration,主要实现内嵌 Redis 的启动
+ *
+ * @author 芋道源码
+ */
 @Configuration(proxyBeanMethods = false)
 @Lazy(false) // 禁止延迟加载
 @EnableConfigurationProperties(RedisProperties.class)
@@ -20,7 +25,7 @@ public class RedisTestConfiguration {
     @Bean
     public RedisServer redisServer(RedisProperties properties) throws IOException {
         RedisServer redisServer = new RedisServer(properties.getPort());
-        // TODO 芋艿:一次执行多个单元测试时,貌似创建多个 spring 容器,导致不进行 stop。这样,就导致端口被占用,无法启动。。。
+        // 一次执行多个单元测试时,貌似创建多个 spring 容器,导致不进行 stop。这样,就导致端口被占用,无法启动。。。
         try {
             redisServer.start();
         } catch (Exception ignore) {}

+ 52 - 0
yudao-framework/yudao-spring-boot-starter-test/src/main/java/cn/iocoder/yudao/framework/test/config/SqlInitializationTestConfiguration.java

@@ -0,0 +1,52 @@
+package cn.iocoder.yudao.framework.test.config;
+
+import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnSingleCandidate;
+import org.springframework.boot.autoconfigure.sql.init.SqlInitializationProperties;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.boot.jdbc.init.DataSourceScriptDatabaseInitializer;
+import org.springframework.boot.sql.init.AbstractScriptDatabaseInitializer;
+import org.springframework.boot.sql.init.DatabaseInitializationSettings;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Lazy;
+
+import javax.sql.DataSource;
+
+/**
+ * SQL 初始化的测试 Configuration
+ *
+ * 为什么不使用 org.springframework.boot.autoconfigure.sql.init.DataSourceInitializationConfiguration 呢?
+ * 因为我们在单元测试会使用 spring.main.lazy-initialization 为 true,开启延迟加载。此时,会导致 DataSourceInitializationConfiguration 初始化
+ * 不过呢,当前类的实现代码,基本是复制 DataSourceInitializationConfiguration 的哈!
+ *
+ * @author 芋道源码
+ */
+@Configuration(proxyBeanMethods = false)
+@ConditionalOnMissingBean(AbstractScriptDatabaseInitializer.class)
+@ConditionalOnSingleCandidate(DataSource.class)
+@ConditionalOnClass(name = "org.springframework.jdbc.datasource.init.DatabasePopulator")
+@Lazy(value = false) // 禁止延迟加载
+@EnableConfigurationProperties(SqlInitializationProperties.class)
+public class SqlInitializationTestConfiguration {
+
+	@Bean
+	public DataSourceScriptDatabaseInitializer dataSourceScriptDatabaseInitializer(DataSource dataSource,
+																				   SqlInitializationProperties initializationProperties) {
+		DatabaseInitializationSettings settings = createFrom(initializationProperties);
+		return new DataSourceScriptDatabaseInitializer(dataSource, settings);
+	}
+
+	static DatabaseInitializationSettings createFrom(SqlInitializationProperties properties) {
+		DatabaseInitializationSettings settings = new DatabaseInitializationSettings();
+		settings.setSchemaLocations(properties.getSchemaLocations());
+		settings.setDataLocations(properties.getDataLocations());
+		settings.setContinueOnError(properties.isContinueOnError());
+		settings.setSeparator(properties.getSeparator());
+		settings.setEncoding(properties.getEncoding());
+		settings.setMode(properties.getMode());
+		return settings;
+	}
+
+}

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

@@ -3,6 +3,8 @@ package cn.iocoder.yudao.module.system.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-system/yudao-module-system-impl/src/test/java/cn/iocoder/yudao/module/system/test/BaseDbUnitTest.java

@@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.system.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 的自动配置类

+ 1 - 0
yudao-module-system/yudao-module-system-impl/src/test/java/cn/iocoder/yudao/module/system/test/BaseRedisUnitTest.java

@@ -1,6 +1,7 @@
 package cn.iocoder.yudao.module.system.test;
 
 import cn.iocoder.yudao.framework.redis.config.YudaoRedisAutoConfiguration;
+import cn.iocoder.yudao.framework.test.config.RedisTestConfiguration;
 import org.redisson.spring.starter.RedissonAutoConfiguration;
 import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
 import org.springframework.boot.test.context.SpringBootTest;

+ 4 - 0
yudao-module-system/yudao-module-system-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:
@@ -23,6 +26,7 @@ spring:
     port: 16379 # 端口(单元测试,使用 16379 端口)
     database: 0 # 数据库索引
 
+
 mybatis:
   lazy-initialization: true # 单元测试,设置 MyBatis Mapper 延迟加载,加速每个单元测试
 

+ 5 - 0
yudao-module-system/yudao-module-system-impl/src/test/resources/sql/create_tables.sql

@@ -394,9 +394,14 @@ CREATE TABLE IF NOT EXISTS "system_social_user" (
 CREATE TABLE IF NOT EXISTS "system_tenant" (
     "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
     "name" varchar(63) NOT NULL,
+    "contact_user_id" bigint NOT NULL,
     "contact_name" varchar(255) NOT NULL,
     "contact_mobile" varchar(255),
     "status" tinyint NOT NULL,
+    "domain" varchar(63) DEFAULT '',
+    "package_id"  bigint NOT NULL,
+    "expire_time" timestamp NOT NULL,
+    "account_count" int NOT NULL,
     "creator" varchar(64) DEFAULT '',
     "create_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
     "updater" varchar(64) DEFAULT '',