代码之家  ›  专栏  ›  技术社区  ›  Zmur

动态创建架构。Spring之前的sql上下文

  •  3
  • Zmur  · 技术社区  · 7 年前

    我正在为项目编写集成测试,我想将所有数据库迁移脚本合并到模式中。Spring之前的sql将其用于填充数据库。 为此,我使用了一个小类来搜索项目中的sql文件,并将它们合并到一个项目中。 我创建了这样一个套件:

    @RunWith(Suite.class)
    @Suite.SuiteClasses({MyTests.class})
    public class SuiteTest {    
        @BeforeClass
        public static void setUp() throws IOException {
            RunMigrations.mergeMigrations();//this one merges all sqls into one file, called schema.sql
        }
    }
    

    那么,这是我的测试:

    @RunWith(SpringJUnit4ClassRunner.class)
    @SpringBootTest(classes = App.class)
    @ActiveProfiles(resolver = CustomActiveProfileResolver.class)
    @ContextConfiguration(classes = App.class)
    public class MyTests extends AbstractTransactionalJUnit4SpringContextTests {
    @PostConstruct
        public void before() {
            mvc = MockMvcBuilders.webAppContextSetup(context).addFilter(springSecurityFilterChain).build();
        }    
        @Test
        @Transactional
        public void Test1(){ //do stuff }
    }
    

    但这并不像我想象的那样有效。看起来Spring试图运行模式。sql比我创建它的速度快,失败如下:

    Caused by: org.hibernate.tool.schema.spi.SchemaManagementException: Schema-validation: missing table [application]
    

    如果我关闭生成模式的代码。sql并让Spring使用已经创建的模式运行,那么一切都很好。但如果我删除模式。sql并让我的类生成它,然后它会如所述失败。 我试图重写SpringJUnit4ClassRunner中的run(RunNotifier notifier)方法,并在调用super之前将迁移合并放在其中。运行(通知程序)方法,但这仍然不起作用。 有没有办法生成该模式。sql在Spring掌握之前?

    P、 S。 我不能在生产环境中使用flyway。也许仅仅在测试中使用它是可能的?

    UPD: 在做了一些实验之后,我对这个进行了测试。yml:

    spring.jpa.hibernate.ddl-auto: none
    

    现在,它加载上下文,执行一个只获取Oauth2令牌的测试,并与其他执行POST和GET请求的测试一起失败,因为它无法执行在测试方法之前放置额外数据的@sql注释。数据库似乎没有任何改动,也就是说没有任何表。

    2 回复  |  直到 7 年前
        1
  •  2
  •   Karol Dowbecki    7 年前

    您可以使用 @TestPropertySource(properties = {"spring.flyway.enabled=true"}) 注释或通过创建 test 具有自己属性文件的Spring概要文件。后者看起来像:

    @RunWith(SpringRunner.class)
    @SpringBootTest
    @ActiveProfiles("test")
    public MyTest {
    

    具有 src/test/resources/application-test.yml 文件:

    spring:
      flyway:
        enabled: true
    

    flyway-core 作为测试范围的依赖项。

    请注意,Spring Boot中的Flyway属性在Spring Boot 2.0中被重命名。

        2
  •  1
  •   Zmur    7 年前

    也许有人会觉得这很有用。 我通过使用exec-maven插件和故障保护插件解决了这个问题。 测试类设置保持不变,我只从套件中删除了@BeforeClass注释。 以下是POM:

    <build>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-surefire-plugin</artifactId>
                    <version>${org.apache.maven.plugins.maven-surefire-plugin-version}</version>
                </plugin>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-failsafe-plugin</artifactId>
                    <version>${org.apache.maven.plugins.maven-failsafe-plugin-version}</version>
                    <executions>
                        <execution>
                            <id>integration-test-for-postgres</id>
                            <phase>integration-test</phase>
                            <goals>
                                <goal>integration-test</goal>
                            </goals>
                        </execution>
                        <execution>
                            <id>verify-for-postgres</id>
                            <phase>verify</phase>
                            <goals>
                                <goal>verify</goal>
                            </goals>
                        </execution>
                    </executions>
                </plugin>
                <plugin>
                    <groupId>org.codehaus.mojo</groupId>
                    <artifactId>exec-maven-plugin</artifactId>
                    <version>${org.codehaus.mojo.exec-maven-plugin-version}</version>
                    <executions>
                        <execution>
                            <id>build-test-environment</id>
                            <phase>generate-test-resources</phase>
                            <goals>
                                <goal>java</goal>
                            </goals>
                        </execution>
                    </executions>
                    <configuration>
                        <!--This class prepares the schema.sql file which is fed to Spring to init DB before tests.-->
                        <mainClass>...GenerateTestDBSchema</mainClass>
                        <arguments>
                            <argument>...</argument><!--the migration folder-->
                            <argument>...</argument><!--The path where to put schema sql-->
                        </arguments>
                    </configuration>
                </plugin>
            </plugins>
        </build>
    

    GenerateTestDBSchema类有main方法,并使用args数组来接受在何处查找迁移和在何处放置模式的路径。sql。

    public static void main(String[] args) {
            try {
                mergeMigrations(args[0], args[1]);
            } catch (IOException e) {
                LOG.error(e.getMessage());
            }
        }
    

    mergeMigrations()方法很简单:只需从目录中获取所有文件,合并它们并写入输出路径。这样,Spring就有了它的模式。在启动上下文之前使用sql,它自己决定在何处运行迁移。 由于集成测试中的@ActiveProfiles(resolver=CustomActiveProfileResolver.class),spring解析概要文件并选择应用程序{profileName}。yml并自动设置数据库地址。