如何在春季每次测试前重新创建数据库?

我的 Spring-Boot-Mvc-Web 应用程序在文件中具有以下数据库配置:application.properties

spring.datasource.url=jdbc:h2:tcp://localhost/~/pdk
spring.datasource.username=sa
spring.datasource.password=
spring.datasource.driver-class-name=org.h2.Driver

这是我唯一的配置。没有我在任何地方进行的任何其他配置。尽管如此,Spring和子系统在每个Web应用程序运行时都会自动重新创建数据库。数据库是在系统运行时重新创建的,而在应用程序结束后它包含数据。

我不理解这个默认值,并期望这适合测试。

但是当我开始运行测试时,我发现数据库只被重新创建一次。由于测试不是以预定义的顺序执行的,因此这毫无意义。

所以,问题是:如何有意义?即如何在每次测试之前重新创建数据库,就像在应用程序首次启动时发生的那样?

我的测试类标头如下:

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = myapp.class)
//@WebAppConfiguration
@WebIntegrationTest
@DirtiesContext
public class WebControllersTest {

如您所见,我在课堂上尝试过,但没有帮助。@DirtiesContext

更新

我有一个豆子

@Service
public class DatabaseService implements InitializingBean {

它有一个方法

@Override
    @Transactional()
    public void afterPropertiesSet() throws Exception {
        log.info("Bootstrapping data...");
        User user = createRootUser();
        if(populateDemo) {
            populateDemos();
        }
        log.info("...Bootstrapping completed");
    }

现在我制作了从数据库中清除所有数据的方法。不幸的是,尽管.为什么?populateDemos()@DirtiesContext


答案 1

实际上,我认为你想要这个:

@DirtiesContext(classMode = ClassMode.BEFORE_EACH_TEST_METHOD)

http://docs.spring.io/autorepo/docs/spring-framework/4.2.6.RELEASE/javadoc-api/org/springframework/test/annotation/DirtiesContext.html

@DirtiesContext可以用作同一类中的类级和方法级批注。在这种情况下,应用程序上下文将在任何此类带注释的方法之后以及整个类之后被标记为脏。如果 DirtiesContext.ClassMode 设置为 AFTER_EACH_TEST_METHOD,则在类中的每个测试方法之后,上下文将被标记为脏。

你把它放在你的测试类上。


答案 2

使用Spring-Boot 2.2.0中接受的答案,我看到与约束相关的JDBC语法错误:

原因: org.h2.jdbc.JdbcSQLSyntaxErrorException: Constraint “FKEFFD698EA2E75FXEERWBO8IUT” 已经存在;SQL 语句: alter table foo add constraint FKeffd698ea2e75fxeerwbo8iut foreign key (bar) references bar [90045-200]

为了解决这个问题,我在我的单元测试中添加了(spring-boot-test-autoconfigure的一部分):@AutoConfigureTestDatabase

import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase;
import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase.Replace;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.annotation.DirtiesContext.ClassMode;
import org.springframework.boot.test.context.SpringBootTest;
import org.junit.runner.RunWith;
import org.springframework.test.context.junit4.SpringRunner;


@RunWith(SpringRunner.class)
@SpringBootTest
@DirtiesContext(classMode = ClassMode.BEFORE_EACH_TEST_METHOD)
@AutoConfigureTestDatabase(replace = Replace.ANY)
public class FooRepositoryTest { ... }

推荐