【发布时间】: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 响应。