Hi,
I'm working on an application which has both component and integration tests. The differences between then is: a component test test more than one class (i.e., its inner objects aren't all mocked out - but some of them might be [such as JMS publishers]) and an Integration test is a test that nothing at all is mocked out. In another words, Spring gives you the object and you test it as it is.
So far, so good.
The problem is: in order to be able to replace one dependency or another from the Spring context, I used Springockito (https://bitbucket.org/kubek2k/springockito/wiki/Home) which offers you a way to mock out some bean from the Spring context.
So - in the component tests - I have this:
Bean has SomeServiceInterface as a depedency.Code:@RunWith(SpringJUnit4ClassRunner.class) @DirtiesContext(classMode = AFTER_CLASS) @ContextConfiguration(loader = SpringockitoContextLoader.class, locations = "classpath:spring-classify-test.xml") public class.... @Autowired @ReplaceWithMock private SomeServiceInterface someServiceInterface; @Autowired private Bean bean;
In the case above, SomeServiceInterface will be replaced by a mock. Of course, that example is an oversimplification of the problem - I replace bean with mock objects that are dependecies further down in the object graph.Code:public class Bean { private SomeServiceInterface...
It's worthy noticing that I load the context from this file: spring-classify-test.xml Also it's wothy noticing that I mark the context as dirty after the execution of the class - so, AFAIK, the next test class must reload the context.
Ok, now the integration test:
I load the context from spring-service-integration-test.xml - but SomeServiceInterface inside of Bean is still mocked! The context used in the integration test was changed as well!Code:@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(loader = SpringockitoContextLoader.class, locations = { "classpath:/spring-service-integration-test.xml" }) public ... @Autowired private Bean bean;
If I mark the Integration test with @DirtiesContext(classMode = ClassMode.AFTER_EACH_TEST_METHOD), the first test in the class will fail because SomeServiceInterface is mocked - but the next test will pass because the context has been refreshed already.
Funny thing is:
If I ask Spring to inject SomeServiceInterface in the Integration Test, it will inject a SomeServiceInterface concrete implementation - not a mock!
I have tried many things to sort out that issue:
1) Programatically override the beans in the context after the component tests are done using the registerBeanDefinition method from the context
2) Create a TestExecution listener so I could try to manually refresh the context before the execution of an IntegrationTest
3) Use the same loader for the different contexts....
4) This story goes on and on.
Does anyone have any idea?
P.S.: I quite understand that adopting Springockito was a dubious idea - but that decision was not made by me and now we have over 500 tests in the project - hence refactoring them all to remove Springockito will be a lenghty task, therefore it is not a viable option ATM.
Cheers.


Reply With Quote