【发布时间】:2011-08-22 09:15:14
【问题描述】:
只是寻找一些关于如何在 Spring 3.0.2 和 Hibernate 3.2.7 Web 应用程序上使用 JUnit4 设置“单元”测试的建议。
我们目前有超过 500 项测试,分布在 75 多个班级。
我们的测试类的设置(注释)类似于下面的类:
@RunWith(SpringJUnit4ClassRunner.class)
@TransactionConfiguration
@Transactional
@ContextConfiguration(locations={"/location/of/SomeServiceTest-context.xml"}, inheritLocations=false)
public class SomeServiceTest extends AbstractTransactionalJUnit4SpringContextTests {
@Autowired
protected SomeService someService;
@Test
public void testSomeServiceMethod() {}
@Test
public void testAnotherServiceMethod() {}
}
我们的“服务”对象使用 @Service("serviceName") 进行注释,并具有 @Autowired(受保护)依赖项,这些依赖项可能是其他服务或 DAO(使用 @Repository("daoName") 进行注释)。
以前,我们对大多数测试类都有不同的上下文。每个上下文只包含该类中测试所需的 bean,因此我们可以单独测试应用程序的各个部分。上下文中未定义的依赖项将由我们创建的 AutoBeanDeclarer 自动模拟,灵感来自 DZone 上的这篇文章:Automatically Inject Mocks into Spring Context
当我们单独运行测试类时,这种设置运行良好。当我们尝试同时运行所有 500 多个测试时,我们遇到了一个
java.lang.OutOfMemoryError: GC overhead limit exceeded
在进行了一些挖掘(和分析)之后,我们发现存在内存泄漏,如本文所述:Application ClassLoader’s Footprint Memory Leak in Shared Containers。简而言之,我们已经加载了多个应用程序上下文的设置,并且由于 ClassLoader 存在附件,它们不是垃圾可收集的。所以我们有大量 (SessionFactory) 对象,这些对象不是垃圾可回收的,而是占用内存。
我们将设置更改为使用所有测试类使用的单个完整应用程序上下文(定义了所有 bean)。这适用于两种情况;单独运行测试并同时运行所有测试时。
但是,我们希望通过此设置克服几个问题:
主要问题是这种设置不允许我们单独测试应用程序的各个部分,因为所有 bean 及其依赖项都是在应用程序上下文中定义的,而不是模拟的。
第二个问题是,当我们运行单个测试时,加载应用程序上下文需要 30-40 秒,当您必须多次运行测试时,这最终会适得其反。
任何建议/提示将不胜感激。
希望我说的够清楚了,有任何问题都可以提出来。
提前致谢
马丁
【问题讨论】:
标签: hibernate unit-testing spring junit4