带有 DB 的 Spring Boot 应用程序 - 使用 @DirtiesContext 重新创建上下文后测试类失败

Posted

技术标签:

【中文标题】带有 DB 的 Spring Boot 应用程序 - 使用 @DirtiesContext 重新创建上下文后测试类失败【英文标题】:Spring Boot Application with DB - Test class fails after context being recreated with @DirtiesContext 【发布时间】:2015-03-05 13:42:58 【问题描述】:

我正在尝试执行 Spring Boot 应用程序的一组 JUnit4 测试类,该应用程序由多个 Web 服务组成并配置了一个数据库。

每次测试后清除上下文很方便,所以我在每个测试类上都包含了一个@DirtiesContext注解,因为这个注解的默认行为设置在AFTER_CLASS。

我遇到的问题是第一个测试类运行良好,但随后的测试类总是失败。

所以我创建了 2 个简单的 JUnit 类来尝试解决这个问题。两者都是相等的,并且测试方法是空的,所以总是应该返回成功:

import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;

import urlshortener2014.goldenbrown.Application;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = Application.class)
@WebAppConfiguration
@IntegrationTest("server.port=0")
@DirtiesContext
public class ApplicationTests 

    @Value("$local.server.port")
    private int port = 0;

    @Test
    public void testAlwaysOk() throws Exception 

    

我已经在 eclipse 中并通过“gradle test”执行了两个测试类(ApplicationTests 和 SameApplicationTests),在这两种情况下,第二个和后续测试类在清除上下文后都失败了。

我怀疑问题与应用程序的数据库有关,没有正确重新创建,因为输出跟踪多次指向与数据库相关的错误。但我不确定这是如何或为什么会发生以及如何解决它。

这是一个带有“gradle test”输出(正常输出、--info 输出和--debug 输出)的要点: https://gist.github.com/jgbarcos/c8b34c5c292ca1fabc1d

这是正在使用的 build.gradle(仅用于测试 2 个简单的类):

eclipse 
   project 
      name = "UrlShortener2014.goldenBrown"
   


dependencies 
   compile project(":common")
     // Provides java script libraries for static content
   compile("org.webjars:bootstrap:3.0.3")
   compile("org.webjars:jquery:2.0.3-1")
   compile 'org.apache.httpcomponents:httpclient:4.3.6'
   compile 'nl.bitwalker:UserAgentUtils:1.2.4'
   compile 'org.springframework:spring-context'
   compile 'org.springframework:spring-context-support'
   compile 'net.sf.ehcache:ehcache:2.7.4'
   compile("org.springframework.boot:spring-boot-starter-web:1.2.0.RELEASE")
   compile 'org.springframework:spring-test:4.1.4.RELEASE'
   testCompile 'junit:junit:4.10'


// Used for @DirtiesContext problem
test
    scanForTestClasses = false
    // This should get only "ApplicationTests.class" and "SameApplicationTests.class"
    include "**/*ApplicationTests.class"

这是我创建的 GitHub 分支,用于重现团队项目文件夹 (goldenBrown) 的问题: https://github.com/jgbarcos/UrlShortener2014/tree/debug_branch/goldenBrown

注意:项目依赖于另一个文件夹“/common”而不是“/goldenBrown”中名为 common 的另一个项目,这可能有点棘手)

希望这有助于理解问题,在此先感谢。

【问题讨论】:

【参考方案1】:

您的代码没问题。故障在schema-hsqldb.sql。只需在文件开头添加以下两行:

DROP TABLE CLICK IF EXISTS;
DROP TABLE SHORTURL IF EXISTS;

这样可以确保每次重新创建数据库时都会删除现有表。

【讨论】:

以上是关于带有 DB 的 Spring Boot 应用程序 - 使用 @DirtiesContext 重新创建上下文后测试类失败的主要内容,如果未能解决你的问题,请参考以下文章

Spring Boot + MySQL docker 容器

带有 Spring Boot 应用程序的 docker secret 在 docker swarm 模式 /run/secrets 下不起作用

大写的mongoDB spring-boot自定义查询,带有LIKE

SQLException:在 Spring Boot 中访问被拒绝

Spring Boot 从类路径加载 H2 db 文件

Java Spring boot hibernate删除级联数据