Note: I have purposefully removed words from the names of classes and objects, so please excuse the horribly names in my code examples
I've got a test class that sets up my application using some test Spring context files. The application is a wrapper to a web service.
As this is a test, I have mocked the main interface to the web service in question (the ITransporter
class). This gives me the ability to set expectations so that I can check that the requests sent to the web service are: in the expected format; have the expected fields complete; etc...
My mock is defined in a file called test-beans-context.xml
and is passed into some service beans, as follows:
<bean id="mockTransporter" class="org.easymock.EasyMock" factory-method="createMock" scope="singleton">
<constructor-arg index="0" value="transport.ITransporter" />
</bean>
<bean id="accountService" class="service.AccountService">
<property name="transporter" ref="mockTransporter" />
</bean>
This context file is used in 2 places. (And I fear this is where my problem arises.)
The first being the test class, which is defined as follows:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration( locations={"classpath:test-beans-context.xml"} )
public class AbstractIntegrationTest {
@Autowired
private ITransporter mockTransporter;
//Some tests that perform expectations like the following:
// EasyMock.reset( this.mockTransporter );
// EasyMock.expect( this.mockTransporter.sendRequest( EasyMock.capture(this.requestXmlCapture) ) ).andReturn( responseXml );
}
The second place is in a class that is within the logical trail for getting to sending the request. It loads a separate XML context file /lite-api-context.xml
that then imports the test one in my test set up.
public class Factory implements IFactory {
public Factory() {
context = new ClassPathXmlApplicationContext("/lite-api-context.xml");
}
@Override
public IAccountService getAccountService() {
return (IAccountService) context.getBean("accountService");
}
}
And lite-api-context.xml
includes this:
<import resource="classpath:/test-beans-context.xml" />
My problem is that in the test class, I'm getting a different instance of the mocked ITransporter
to the one that is ultimately being used by my other services. So the expectations I set up are never actually executed as the mocks end up being different instances.
Is there a way to ensure I get the same instance in both places?
Or am I going to have to create my own singleton test implementation of the ITransporter
interface? (Basically creating a stub that behaves exactly like my mock does now.)
EDIT: (Answer)
As The Thom said, it appears I need to create my own class to manage the mock.
I wanted to add my solution here too in case anyone stumbled across a similar problem.
Just wrote a quick static class like this:
public class MockTransporter {
private static ITransporter mockTransporter = EasyMock.createMock(ITransporter.class);
public static final ITransporter getInstance() {
return mockTransporter;
}
}
And had to change the XML config to this:
<bean id="mockTransporter" class="MockTransporter" factory-method="getInstance" />