我正在为项目编写集成测试,我想在Spring选择填充数据库之前将所有数据库迁移脚本合并到schema.sql中。 为此,我使用一个小类,在项目中搜索sql文件并将它们合并为一个。 我创建了一个像这样的套件:
aL->add(element)
然后,这是我的测试:
@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
}
}
但这并不像我想的那样有效。看起来Spring试图以比我创建它更快的速度运行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 }
}
如果我只是关闭生成schema.sql的代码并让Spring运行已经创建的架构,那么一切都很好。但是如果我删除schema.sql并让我的类生成它,那么它就会失败,如上所述。 我试图在SpringJUnit4ClassRunner中覆盖run(RunNotifier通知程序)方法并在我调用super.run(notifier)方法之前将我的迁移合并放在那里,但这仍然无效。 有没有办法在Spring获得它之前生成该schema.sql?
P.S。 我不能将flyway用于生产环境。也许它可以用于测试吗?
UPD: 经过一些实验,我在test.yml中设置了这个:
Caused by: org.hibernate.tool.schema.spi.SchemaManagementException: Schema-validation: missing table [application]
现在它加载上下文,执行一个只获取Oauth2令牌的测试,并且执行POST和GET请求的其他测试失败,因为它无法执行在测试方法之前放置其他数据的@sql注释。数据库似乎没有变化,没有任何表格。
答案 0 :(得分:2)
您可以通过使用@TestPropertySource(properties = {"spring.flyway.enabled=true"})
注释或使用自己的属性文件创建test
Spring配置文件来启用flyway。后者看起来像:
@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中重命名。
答案 1 :(得分:1)
也许有人会觉得这很有用。 我设法通过使用带有故障安全插件的exec-maven-plugin来解决这个问题。 测试类设置保持不变,我只从Suite中删除了@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数组接受查找迁移的路径以及schema.sql的放置位置。
public static void main(String[] args) {
try {
mergeMigrations(args[0], args[1]);
} catch (IOException e) {
LOG.error(e.getMessage());
}
}
mergeMigrations()方法很简单:只需从目录中获取所有文件,合并它们并写入输出路径。这样,Spring在启动上下文之前就拥有了schema.sql,它本身决定了迁移的运行位置。 感谢集成测试中的@ActiveProfiles(resolver = CustomActiveProfileResolver.class),spring解析配置文件并获取application- {profileName} .yml并自动设置数据库地址。