Spring 每次测试后用Flyway清理数据库

Spring 每次测试后用Flyway清理数据库,spring,junit5,flyway,Spring,Junit5,Flyway,我们处于测试后无法简单回滚数据的情况,因此我们决定使用Flyway java API,如下所示: @Autowired protected Flyway flyway; @AfterEach public void restoreDatabase() { flyway.clean(); flyway.migrate(); } 是否可以在每个测试类之后执行清理和迁移,而不是测试方法?我需要在带注释的静态方法中调用它,但是这种方法必须是静态的,所以我不能使用自动连线

我们处于测试后无法简单回滚数据的情况,因此我们决定使用Flyway java API,如下所示:

 @Autowired
 protected Flyway flyway;

 @AfterEach
 public void restoreDatabase() {
     flyway.clean();
     flyway.migrate();
 }

是否可以在每个测试类之后执行清理和迁移,而不是测试方法?我需要在带注释的静态方法中调用它,但是这种方法必须是静态的,所以我不能使用自动连线组件
Flyway
。你能给我一些解决办法吗?谢谢。

以下解决方案可能会对您有所帮助

除了@Rollback注释外,还可以使用注释
org.springframework.test.annotation.DirtiesContext
将类(或方法)标记为“dirty”。这将为测试用例提供一个新的上下文。从Java文档:

测试注释,指示与测试关联的ApplicationContext是脏的,因此应关闭并从上下文缓存中删除

如果测试修改了上下文,请使用此注释-例如,通过修改单例bean的状态、修改嵌入式数据库的状态等。请求相同上下文的后续测试将提供一个新上下文

@DirtiesContext可以用作同一类或类层次结构中的类级和方法级注释。在这种情况下,根据配置的methodMode和classMode,ApplicationContext将在任何此类带注释的方法之前或之后以及当前测试类之前或之后标记为dirty

让我给你举个例子:

@RunWith(SpringRunner.class)
@SpringBootTest
@DirtiesContext(classMode = ClassMode.BEFORE_CLASS)
public class SomeTestClass {

@Autowired
private ExampleController controller;

@Test
public void testSomething() {
   //Do some testing here
}
现在,在这种情况下,使用嵌入式数据库(如H2),将启动一个新的数据库,其中不包含以前事务的任何更改

请注意,这很可能会减慢测试用例的速度,因为创建新的上下文可能会很耗时

编辑:

@RunWith(SpringRunner.class)
@SpringBootTest
@DirtiesContext(classMode = ClassMode.BEFORE_CLASS)
public class SomeTestClass {

@Autowired
private ExampleController controller;

@Test
public void testSomething() {
   //Do some testing here
}
如果您观察日志输出,您将看到Spring创建了一个包含所有内容的新应用程序上下文。因此,当在测试用例中使用嵌入式DB时,Spring将删除当前DB并创建一个新DB,并运行所有指定的迁移。这就像重新启动服务器一样,也会创建一个新的嵌入式数据库


新数据库不包含以前操作的任何提交。这就是它起作用的原因。事实上,这并不是黑客攻击,而是集成测试的适当设置,因为集成测试会弄乱数据库,需要同样干净的设置。然而,很可能还有其他解决方案,因为为每个测试类创建新上下文可能会降低执行时间。因此,我建议只注释真正需要它的类(或方法)。另一方面,单元测试在大多数情况下不是非常时间关键的,对于较新的Spring版本,延迟加载将加快启动时间。

以下解决方案可能会对您有所帮助

除了@Rollback注释外,还可以使用注释
org.springframework.test.annotation.DirtiesContext
将类(或方法)标记为“dirty”。这将为测试用例提供一个新的上下文。从Java文档:

测试注释,指示与测试关联的ApplicationContext是脏的,因此应关闭并从上下文缓存中删除

如果测试修改了上下文,请使用此注释-例如,通过修改单例bean的状态、修改嵌入式数据库的状态等。请求相同上下文的后续测试将提供一个新上下文

@DirtiesContext可以用作同一类或类层次结构中的类级和方法级注释。在这种情况下,根据配置的methodMode和classMode,ApplicationContext将在任何此类带注释的方法之前或之后以及当前测试类之前或之后标记为dirty

让我给你举个例子:

@RunWith(SpringRunner.class)
@SpringBootTest
@DirtiesContext(classMode = ClassMode.BEFORE_CLASS)
public class SomeTestClass {

@Autowired
private ExampleController controller;

@Test
public void testSomething() {
   //Do some testing here
}
现在,在这种情况下,使用嵌入式数据库(如H2),将启动一个新的数据库,其中不包含以前事务的任何更改

请注意,这很可能会减慢测试用例的速度,因为创建新的上下文可能会很耗时

编辑:

@RunWith(SpringRunner.class)
@SpringBootTest
@DirtiesContext(classMode = ClassMode.BEFORE_CLASS)
public class SomeTestClass {

@Autowired
private ExampleController controller;

@Test
public void testSomething() {
   //Do some testing here
}
如果您观察日志输出,您将看到Spring创建了一个包含所有内容的新应用程序上下文。因此,当在测试用例中使用嵌入式DB时,Spring将删除当前DB并创建一个新DB,并运行所有指定的迁移。这就像重新启动服务器一样,也会创建一个新的嵌入式数据库


新数据库不包含以前操作的任何提交。这就是它起作用的原因。事实上,这并不是黑客攻击,而是集成测试的适当设置,因为集成测试会弄乱数据库,需要同样干净的设置。然而,很可能还有其他解决方案,因为为每个测试类创建新上下文可能会降低执行时间。因此,我建议只注释真正需要它的类(或方法)。另一方面,单元测试在大多数情况下都不是非常时间关键的,对于较新的Spring版本,延迟加载将加快启动时间。

我从未尝试过,但您可以使用setter注入并写入静态字段,然后在after all方法中访问该字段。这里有一个例子:你说“你不能回滚”是什么意思?有这样一个org.springframework.test.annotation.Rollback注释,它将在类级别上新启动服务器(包括所有迁移)。与内存中的DB(如H2)相结合,您应该能够实现您想要的功能want@Vetemi例如,我们在一个较大的once中嵌套了事务,之后由于嵌套事务数据没有回滚EDI从未尝试过,但您可以使用setter注入并写入静态字段,然后在after all方法中访问该字段。这里有一个例子:你说“你不能回滚”是什么意思?有一个org.springframework.test.annotation.Rollback注释,它将在类级别新启动服务器