I have a test class that looks like
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:/test-context.xml"})
@DirtiesContext(classMode = ClassMode.AFTER_EACH_TEST_METHOD)
public abstract class TestClass {
@Rule @Resource public JUnitRuleMockery jMockContext;
public void test1() {
//Expectations and test
}
public void test2() {
//Expectations and test
}
}
and in test-context.xml
I define the JUnitRuleMockery
plus several mock objects through a factory-method
, like
<bean id="mockContextFactory" class="MockContextFactory" />
<bean id="jMockContext" factory-bean="mockContextFactory" factory-method="getContext" scope="prototype" />
<bean id="firstMock" factory-bean="mockContextFactory" factory-method="getFirstMock" />
<bean id="secondMock" factory-bean="mockContextFactory" factory-method="getSecondMock" />
MockContextFactory
is
public class MockContextFactory
{
private JUnitRuleMockery jUnitRuleMockery;
public MockContextFactory() {
jUnitRuleMockery = new JUnitRuleMockery();
jUnitRuleMockery.setThreadingPolicy(new Synchroniser());
}
public JUnitRuleMockery getContext() {
return jUnitRuleMockery;
}
public FirstMock getFirstMock() {
return jUnitRuleMockery.mock(FirstMock.class);
}
//others getter
}
In TestClass
I have several test methods and, due to the annotations @DirtiesContext
, I am expecting the Spring context to be reloaded after each test execution (since each test sets expectations on mock objects, I have to reload Spring context every time). See @DirtiesContext from here. However, it appears that the Spring context is not reloaded: in fact, entering in debug mode at the beginning of test2
(supposedly test1
has been executed earlier) I can see jMockContext
still holding expectations, execution list and errors (if any) from test1
.
So, to end up with few questions, does @DirtiesContext
really cause Spring context to be reloaded (as I understood from Spring Docs) or did I misunderstand the annotation? In the first case, what am I doing wrong? In the latter case, how can I force Spring context to be reloaded for every test?
EDIT, to delimit the problem: I had a code like the sample above running from few days, then today I created a new test in which I added an expectation which failed. Then, I saw all the other tests in the class failing for the same reason (while they where green
until today). Debugging, I found out that jMockContext
was never cleared, which means all tests were adding expectations to the same pool: of course, as long as no expectation failed, that was transparent and I did not notice it (test1
adds and passes few expectations, test2
takes a not-empty pool of expectations ALREADY passed and adds its own so there was no problem), but I do not like the previous situation and I would like to start each test with no previous set expectations at all.
Here is my solution. I do not know if this is limited to Spring 3.2 or if it is a general misunderstanding, but simply using @DirtiesContext(classMode = ClassMode.AFTER_EACH_TEST_METHOD)
is not enough to cause the entire Spring context to be reloaded for each test. I had to add also the DirtiesContextTestExecutionListener
in @TestExecutionListeners
.
So, in the end, what worked for me was just to change the annotation of my TestClass
to
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:/test-context.xml"})
@DirtiesContext(classMode = ClassMode.AFTER_EACH_TEST_METHOD)
@TestExecutionListeners({DirtiesContextTestExecutionListener.class})
public abstract class TestClass
Nothing else has to change.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With