Reputation: 2311
I am trying to unit test a Spring MVC based Controller. This controller calls out to a service. That service is actually remote, and is exposed to the controller via JSON-RPC, and specifically, a com.googlecode.jsonrpc4j.spring.JsonProxyFactoryBean
The Controller has:
@Controller
@RequestMapping("/users")
public class UserController {
/**
* ID manager service that will be used.
*/
@Autowired
IdMService idMService;
...
@ResponseBody
@RequestMapping(value = "/{userId}", method = GET)
public UserAccountDTO getUser(@PathVariable Long userId, HttpServletResponse response) throws Exception {
try {
return idMService.getUser(userId);
} catch (JsonRpcClientException se) {
sendJsonEncodedErrorRepsonse(response, se);
return null;
}
}
...
}
The spring configuration provides the IdMService like this:
<!-- Create the proxy for the Access Control service -->
<bean class="com.googlecode.jsonrpc4j.spring.JsonProxyFactoryBean">
<property name="serviceUrl" value="${access_control.service.url}" />
<property name="serviceInterface" value="com.phtcorp.service.accesscontrol.IdMService" />
</bean>
Thus, the IdMService that gets injected into the controller is actually a JSON-RPC proxy, implementing the IdMService interface.
I would like to test the controller, but mock the IdMService. I have this:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath:/test-context.xml" })
@SuppressWarnings("javadoc")
public class TestUserController {
@Autowired
private ApplicationContext applicationContext;
private HandlerAdapter handlerAdapter;
private MockHttpServletRequest request;
private MockHttpServletResponse response;
@Mocked IdMService service;
@Test
public void getUser() throws Exception {
request.setMethod(RequestMethod.GET.name());
request.setRequestURI("/users/1");
HandlerMethod handler = (HandlerMethod) getHandler(request);
handlerAdapter.handle(request, response, handler);
new Verifications() {{
service.getUser(1L); times=1;
}};
}
...
}
However, I find that IdMService that is injected into the controller is not a mock, it is a JsonRpcProxy after all. I have successfully tested a different controller in this manner, but that one does not use a proxy to its service.
So the question is: how do I use jmockit to cause a mock IdMService to be injected into the UserController? Note that I'm not instantiating the UserController myself, anywhere; spring/spring-mvc does that.
Thanks for any help!
Upvotes: 2
Views: 3328
Reputation: 2311
I solved my problem by injecting the mock myself:
@Mocked IdMService service;
@Before
public void setUp() {
controller.setIdMService(service);
...
}
Upvotes: 0
Reputation: 7218
Note that I'm not instantiating the UserController myself, anywhere; spring/spring-mvc does that.
This means that you're not writing a unit test. This is testing the spring wiring which makes it an integration test. When writing a unit test you instantiate the class under test and supply the dependencies yourself. This allows you to isolate the logic in the class being tested by providing mocked instances of the classes dependencies. That's where jmockit comes in.
Upvotes: 1
Reputation: 6186
If you are unit testing your UserController, why not just instantiate it yourself. Get Spring out of the picture and just test it all on its own.
You are not testing the UserController here so much as testing the Spring wiring of it and the request mapping for it.
Upvotes: 1