如何在 Spring 的每次测试之前重新创建数据库?

新手上路,请多包涵

我的 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 ,它并没有在每次测试之前调用。为什么?

原文由 Dims 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 694
2 个回答

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

 @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 可以用作同一类中的类级别和方法级别注释。在这种情况下,ApplicationContext 将在任何此类带注释的方法之后以及整个类之后被标记为脏。如果 DirtiesContext.ClassMode 设置为 AFTER_EACH_TEST_METHOD,则在类中的每个测试方法之后,上下文将被标记为脏。

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

原文由 Raphael Amoedo 发布,翻译遵循 CC BY-SA 4.0 许可协议

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

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

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

 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 { ... }

原文由 Zack 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题