【问题标题】:Integration tests of Spring applicationSpring应用的集成测试
【发布时间】:2018-01-26 16:46:15
【问题描述】:

我正在尝试为我的 Tomcat 应用程序实现集成测试,但我的问题是应用程序是与测试分开启动的,因此测试无法访问应用程序上下文,也无法访问数据库。

我的想法是在正在运行的应用程序“内”运行测试,因此我可以@Autowire EntityManager 并在测试期间检查例如数据库的状态,甚至创建用于测试的数据库实体。

我这样做的唯一想法是从测试中以ClassPathXmlApplicationContext("applicationContext.xml") 的身份以编程方式实际运行应用程序并访问上下文。这会起作用,但调试起来会非常困难,因为我们在测试期间无法使用 Hotswapping。我也猜想一旦测试结束,服务器就会停止。我想这不是最好和正确的解决方案。

编辑:

我的问题可能不清楚,所以我会尽力澄清。

我有一个带有 Spring 和 Hibernate 的 Tomcat 应用程序。 Spring bean 和 Hibernate 数据库连接在 Tomcat 应用程序启动时初始化。问题是如何从单独启动的src/test/java 中用@Test 注释的方法运行活动 Spring bean 的测试。

考虑这个类:

@Component
class MyRepository {

    @Autowired
    EntityManager em;

    @Transactional
    public void myMethod(MyEntity entity) {
        // do some job with entity
        ...
        em.flush();
    }
}

这个类将被 Tomcat 初始化为 MyRepository bean。

要测试它,我不能只调用new MyRepository().myMethod(...) - 我需要访问 bean。问题是从@Test 方法访问bean:

@Test
void testMyRepository() {
    Item item = ...
    // then use the repository to handle the entity 
    context.getBean(MyRepository.class).myMethod(item);

    // then assert the state of the database
    context.getBean(EntityManager.class).find(Item.class, ...) ...
}

我可能会在测试的初始化中获得context

ApplicationContext context = ClassPathXmlApplicationContext("applicationContext.xml");

但这意味着每次启动测试时都会启动整个应用程序。更好的解决方案是应用程序可以与测试分开运行。

希望我的问题现在更清楚了。

【问题讨论】:

  • 很难知道你在这里实际问的是什么。您主要关心的似乎是能够打开到基本上手动启动的服务器的调试会话?
  • Vojtěch,我理解正确吗 - 您不能使用标准 SpringRunner 并从您的测试中启动 Spring 应用程序上下文。您的测试应该连接到应用程序的外部实例吗?您的应用程序是否有一些(REST)API?您想测试单个 Spring bean 还是整个应用程序(从其 API 到 DB 层)?你能解释一下原因吗?
  • 应用程序连接到 SQL 数据库和潜在的其他来源(如弹性搜索的测试实例)。它可以由像 SpringRunner 这样的人启动,我的问题是我不知道正确的方法是什么。而且——在每次测试之前启动应用程序将非常耗时,因为启动应用程序大约需要 30-60 秒。最好的情况是测试可以独立运行。该应用程序有一个 API,但我想测试系统的更深层部分,而不仅仅是 API 响应。

标签: java spring testing junit


【解决方案1】:

我建议您使用 SpringRunner 来启动 Spring 应用程序上下文并在该运行实例上执行测试。您可以自定义上下文,使其不包含您不想测试的部分,并且可以为需要一些外部资源(REST 客户端等)的组件创建模拟。看看Spring docsSpring Boot docs

如果多个测试使用相同的 Spring 上下文配置,则上下文只启动一次并重用。因此,最好将它的配置放在测试的父类中。您可以将任何 Spring bean 自动装配到您的测试中并对其进行测试。

您可以使用内存数据库(例如H2)而不是生产数据库,因此您的测试不依赖于外部基础架构。要初始化数据库,请使用FlywayLiquibase 等工具。每次测试前清空数据库,可以使用@Sql注解。

您可以找到许多具有此类测试的项目示例,例如我自己的demo

如果您想测试外部系统,我建议您使用JMeter

【讨论】:

  • SpringRunner 是要走的路。谢谢
【解决方案2】:

不幸的是,您不能镜像您的课程并在测试中使用它们。这是 Web 服务的一大缺点。它们总是依赖于用户/机器交互。通过大量的努力,您可以使用 jUnit 提取基本类或方法的功能并构建测试场景等。 您的可能性概述:

  • 特殊驱动程序和占位符
  • 您可以使用具有详细日志级别和文件输出的记录器。然后,您创建了具有预期结果的场景并将其与您的日志文件进行比较。

  • 捕获回放工具。他们会记录您的执行并重放以进行监控。

  • 我还可以推荐使用 Selenium 进行前端测试。

希望对您有所帮助。

【讨论】:

    猜你喜欢
    • 2010-11-21
    • 1970-01-01
    • 2014-11-26
    • 1970-01-01
    • 1970-01-01
    • 2020-02-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多