ethesx ethesx - 3 months ago 30
Java Question

Inject mock into Spring MockMvc WebApplicationContext

I'm working to test (via JUnit4 and Spring MockMvc) a REST service adapter using Spring-boot. The adapter simply passes along requests made to it, to another REST service (using a custom

) and appends additional data to the responses.

I'd like to run
tests to perform controller integration tests, but want to override the
in the controller with a mock to allow me to predefine the 3rd party REST response and prevent it from being hit during each test. I've been able to accomplish this by instantiating a
and passing it the controller to be tested with the mock injected as listed in this post (and my setup below), however I am not able to do the same using

I've been through a few other posts, none of which answer the question as to how this might be accomplished. I would like to use the actual Spring application context for the tests instead of a standalone to prevent any gaps as the application is likely to grow.

EDIT: I am using Mockito as my mocking framework and am trying to inject one of its mocks into the context. If this isn't necessary, all the better.


public class Controller{

private DataProvider dp;

private RestTemplate template;

@RequestMapping(value = Constants.REQUEST_MAPPING_RESOURCE, method = RequestMethod.GET)
public Response getResponse(
@RequestParam(required = true) String data,
@RequestParam(required = false, defaultValue = "80") String minScore
) throws Exception {

Response resp = new Response();

// Set the request params from the client request
Map<String, String> parameters = new HashMap<String, String>();
parameters.put(Constants.PARAM_DATA, data);
parameters.put(Constants.PARAM_FORMAT, Constants.PARAMS_FORMAT.JSON);

resp = template.getForObject(Constants.RESTDATAPROVIDER_URL, Response.class, parameters);

if(resp.getError() == null){
resp.filterScoreLessThan(new BigDecimal(minScore));
new DataHandler(dp).populateData(resp.getData());
return resp;

Test class:

@SpringApplicationConfiguration(classes = MainSpringBootAdapter.class)
public class WacControllerTest {

private static String controllerURL = Constants.REQUEST_MAPPING_PATH + Constants.REQUEST_MAPPING_RESOURCE + compressedParams_all;
private static String compressedParams_all = "?data={data}&minScore={minScore}";

private WebApplicationContext wac;

private MockMvc mockMvc;

private Controller Controller;

private RestTemplate rt;

private String file;

private DataProvider dp;

public void setup() throws Exception {
dp = new DataProvider(file);
this.mockMvc = MockMvcBuilders.standaloneSetup(controller).build();

public void testGetResponse() throws Exception {

String[] strings = {"requestData", "100"};

rt.getForObject(Mockito.<String> any(), Mockito.<Class<Object>> any(), Mockito.<Map<String, ?>> any()))

mockMvc.perform(get(controllerURL, strings)

Mockito.verify(rt, Mockito.times(1)).getForObject(Mockito.<String> any(), Mockito.<Class<?>> any(), Mockito.<Map<String, ?>> any());


private Response populateTestResponse() {
Response resp = new Response();

resp.setScore(new BigDecimal(100));
resp.setData("Some Data");

return resp;

mzc mzc

Spring's MockRestServiceServer is exactly what you're looking for.

Short description from javadoc of the class:

Main entry point for client-side REST testing. Used for tests that involve direct or indirect (through client code) use of the RestTemplate. Provides a way to set up fine-grained expectations on the requests that will be performed through the RestTemplate and a way to define the responses to send back removing the need for an actual running server.

Try to set up your test like this:

@ContextConfiguration(classes = {YourSpringConfig.class})
public class ExampleResourceTest {

    private MockMvc mockMvc;
    private MockRestServiceServer mockRestServiceServer;

    private WebApplicationContext wac;

    private RestOperations restOperations;

    public void setUp() throws Exception {
        mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
        mockRestServiceServer = MockRestServiceServer.createServer((RestTemplate) restOperations);

    public void testMyApiCall() throws Exception {
        // Following line verifies that our code behind /api/my/endpoint made a REST PUT
        // with expected parameters to remote service successfully


    private void expectRestCallSuccess() {
            .andRespond(withSuccess("{\"message\": \"hello\"}", APPLICATION_JSON));