java - Spring应用的集成测试

标签 java spring testing junit

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

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

我这样做的唯一想法是通过测试以编程方式实际运行应用程序作为 ClassPathXmlApplicationContext("applicationContext.xml") 并访问上下文。这会工作,但调试起来会非常困难,因为我们无法在测试期间使用热交换。另外我猜服务器会在测试结束后立即停止。我想这不是最佳和正确的解决方案。

编辑:

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

我有一个带有 Spring 和 Hibernate 的 Tomcat 应用程序。 Spring bean 和 Hibernate 数据库连接在 Tomcat 应用程序启动时初始化。问题是如何从单独启动的 src/test/java 中用 @Test 注释的方法运行 Activity 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");

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

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

最佳答案

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

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

您可以使用内存数据库(例如 H2 )而不是生产数据库,因此您的测试不依赖于外部基础设施。要初始化数据库,请使用 Flyway 等工具或 Liquibase .要在每次测试前清除数据库,您可以使用 @Sql注释。

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

如果你想测试一个外部系统,我会建议像 JMeter 这样的东西.

关于java - Spring应用的集成测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48446812/

相关文章:

android - 直接在手机上运行 Robotium 测试用例(不是模拟器)

java - 如何将电子邮件和密码值保存在从选择查询检索到的变量中

java - 具有不同时间差的调度程序

java - 如何使用 java-google-translate-text-to-speech api?

java - Spring 数据 JPA : How not to repeat myself in countQueries?

spring - 如何阻止 Spring Security 创建新 session ?

selenium - 有没有类似于Selenium的免代码解决方案?

java - 在 Android 中管理多个 EditText

java - 选择 Distinct * 作为查询方法?

hibernate - AbstractTransactionalJUnit4SpringContextTests