Spring应用程序的集成测试

时间:2018-01-25 15:46:54

标签: java spring testing junit

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

我的想法是运行测试"在"正在运行的应用程序,所以我可以@Autowire EntityManager并在测试期间检查数据库的状态,甚至创建数据库实体进行测试。

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

编辑:

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

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

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

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

1 个答案:

答案 0 :(得分:2)

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

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

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

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

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