我正在尝试为我的Tomcat应用程序实现集成测试,但我的问题是应用程序是与测试分开启动的,因此测试无法访问应用程序上下文,也无法访问数据库。
我的想法是运行测试"在"正在运行的应用程序,所以我可以@Autowire EntityManager并在测试期间检查数据库的状态,甚至创建数据库实体进行测试。
我这样做的唯一想法是实际以编程方式从ClassPathXmlApplicationContext("applicationContext.xml")
开始运行应用程序并访问Context。这可行,但调试非常困难,因为我们无法在测试期间使用Hotswapping。此外,我猜测一旦测试结束,服务器就会停止。我想这不是最好和最正确的解决方案。
编辑:
我的问题可能不清楚,所以我会尽力澄清。
我有一个使用Spring和Hibernate的Tomcat应用程序。启动Tomcat应用程序时,将初始化Spring bean和Hibernate数据库连接。问题是如何从@Test
中src/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");
但这意味着每次测试开始时都会启动整个应用程序。如果应用程序可以与测试分开运行,那么更好的解决方案就是。
希望我的问题现在更清楚了。
答案 0 :(得分:2)
我建议您使用SpringRunner启动Spring应用程序上下文并对正在运行的实例执行测试。您可以按照不包含不需要测试的部分的方式自定义上下文,并且可以为需要某些外部资源的组件(REST客户端等)创建模拟。请查看Spring docs或Spring Boot docs。
如果多个测试使用相同的Spring上下文配置,则上下文仅启动一次并重用。因此,在测试的父类中进行配置是件好事。您可以将任何Spring bean自动装配到您的测试中并进行测试。
您可以使用内存数据库(例如H2)而不是生产数据库,因此您的测试不依赖于外部基础结构。要初始化数据库,请使用Flyway或Liquibase等工具。要在每次测试之前清除数据库,可以使用@Sql注释。
您可以找到许多具有此类测试的项目示例,例如我自己的demo。
如果您想测试外部系统,我建议使用JMeter。