Let's try to test the flow from MessageRouter to Persister via JSONHandler (please refer to the previous post) .
First of all, it won't be a unit test but an integration test as we need to start-up the spring context and test the flow between components.
Let's prepare spring xml config:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="UTF-8"?> | |
<beans xmlns="http://www.springframework.org/schema/beans" | |
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | |
xsi:schemaLocation=" | |
http://www.springframework.org/schema/beans | |
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd"> | |
<import resource="../../../spring-context.xml"/> | |
<bean id="messageRouter" class="org.mockito.Mockito" factory-method="mock"> | |
<constructor-arg value="pl.mjedynak.spring.MessageRouter"/> | |
</bean> | |
<bean id="XMLHandler" class="org.mockito.Mockito" factory-method="mock"> | |
<constructor-arg value="pl.mjedynak.spring.XMLHandler"/> | |
</bean> | |
<bean id="JSONHandler" class="org.mockito.Mockito" factory-method="mock"> | |
<constructor-arg value="pl.mjedynak.spring.JSONHandler"/> | |
</bean> | |
<bean id="persister" class="org.mockito.Mockito" factory-method="mock"> | |
<constructor-arg value="pl.mjedynak.spring.Persister"/> | |
</bean> | |
</beans> |
The test would look like:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@RunWith(SpringJUnit4ClassRunner.class) | |
@ContextConfiguration | |
public class AppIntegrationTest { | |
@Autowired | |
private MessageChannel messageChannel; | |
@Autowired | |
private MessageRouter messageRouter; | |
@Autowired | |
private JSONHandler jsonHandler; | |
@Autowired | |
private XMLHandler xmlHandler; | |
@Autowired | |
private Persister persister; | |
@Before | |
public void resetMocks() { | |
reset(messageRouter, jsonHandler, xmlHandler, persister); | |
} | |
@Test | |
public void shouldRouteToPersisterViaJSONHandler() { | |
String message = "json message"; | |
given(messageRouter.route(message)).willReturn("JSONChannel"); | |
given(jsonHandler.process(message)).willReturn(message); | |
messageChannel.send(MessageBuilder.withPayload(message).build()); | |
verify(persister).persist(message); | |
} | |
} |
By looking at the source code we don't see which object is mocked. To solve this problem (and simplify the code as well) we can use springockito.
Then in our config file we only need to import the application config without overriding any beans.
The overriding part is done in the test by using annotations:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@RunWith(SpringJUnit4ClassRunner.class) | |
@ContextConfiguration(loader = SpringockitoContextLoader.class) | |
@DirtiesMocks(classMode = DirtiesMocks.ClassMode.AFTER_EACH_TEST_METHOD) | |
public class AppIntegrationTest { | |
@Autowired | |
private MessageChannel messageChannel; | |
@Autowired | |
@ReplaceWithMock | |
private MessageRouter messageRouter; | |
@Autowired | |
@ReplaceWithMock | |
private JSONHandler jsonHandler; | |
@Autowired | |
@ReplaceWithMock | |
private XMLHandler xmlHandler; | |
@Autowired | |
@ReplaceWithMock | |
private Persister persister; | |
@Test | |
public void shouldRouteToPersisterViaJSONHandler() { | |
String message = "json message"; | |
given(messageRouter.route(message)).willReturn("JSONChannel"); | |
given(jsonHandler.process(message)).willReturn(message); | |
messageChannel.send(MessageBuilder.withPayload(message).build()); | |
verify(persister).persist(message); | |
} | |
} |
The @ReplaceWithMock annotation is self-descriptive.
The context is dirtied after execution of each test method which is basically equivalent to resetting the mocks.
Whole project can be found at github.