Just looking for a bit of advice really on how to setup "unit" testing with JUnit4 on a Spring 3.0.2 & Hibernate 3.2.7 web app.
We currently have just over 500 tests spread across 75+ classes.
Our test classes are setup (annotated) similar to the class below:
@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() {}
}
Our "Service" objects are annotated with @Service("serviceName") and have @Autowired (protected) dependencies which could be other services or DAOs (annotated with @Repository("daoName")).
Previously, we had different contexts for most test classes. Each context contained just the required beans for the tests in that class so we could test parts of the application in isolation. The dependencies which were not defined in the context would be automatically mocked by an AutoBeanDeclarer we created, inspired by this article on DZone: Automatically Inject Mocks into Spring Context
This kind of setup worked fine when we ran the test classes individually. When we tried to run all the 500+ tests at the same time, we encountered a
java.lang.OutOfMemoryError: GC overhead limit exceeded
After doing some digg开发者_Python百科ing around (and profiling), we discovered that there was a memory leak as explained in this post: Application ClassLoader’s Footprint Memory Leak in Shared Containers. In short, the setup we had loaded multiple application contexts and they were not garbage collectable due to there being an attachment to the ClassLoader. So we had a load of (SessionFactory) objects that were not garbage collectable holding on to memory.
We changed our setup to use a single, full application context (with all the beans defined) used by all test classes. This works for both cases; when running tests individually and running all the tests together.
However, there are a couple of issues that we're looking to overcome with this setup:
The main issue is that this setup doesn't allow us to test parts of the app in isolation because all the beans and their dependencies are defined in the app context, not mocked.
Second issue is that when we're running individual tests, it takes 30-40 seconds to load up the application context, which ends up being quite counter productive when you have to run the test several times.
Any suggestions/tips would be much appreciated.
I hope I was clear enough, feel free to ask any questions.
Thanks in advance
Martin
Spring 3.1 will introduce XML Profiles - this can be a good way how you can work with different test setups. It should be released this year - although they have already a delay in releasing the RC1. Nevertheless I would give the Milestone release a try (I already did).
精彩评论