I am using MockMvc to test a controller. The controller has an ObjectMapper and HttpServletRequest as arguments. I instantiate the controller in my test class with these arguments. When I use MockMvc to make the request, the Name @RequestParam is successfully passed to the controller. However outside of this, the request is null. The accept header is set on the MockMvc request as:
mockMvc.perform(get("/birthday-cards?name=Jack").accept(MediaType.APPLICATION_JSON)).andExpect(status().isOk()).andDo(print());
when the request is accessed in the controller, the request header is null.
String accept = request.getHeader("Accept");
I believe this is because once I get into the controller method body, the request is using the MockHttpServletRequest created when initializing the Controller in the test class.
The full code of the controller:
@Controller
public class HappyBirthdayApiController implements HappyBirthdayApi {
private final ObjectMapper objectMapper;
private final HttpServletRequest request;
@Autowired
public HappyBirthdayController(ObjectMapper objectMapper, HttpServletRequest request) {
this.objectMapper = objectMapper;
this.request = request;
}
@Override
public Optional<ObjectMapper> getObjectMapper() {
return Optional.ofNullable(objectMapper);
}
@Override
public Optional<HttpServletRequest> getRequest() {
return Optional.ofNullable(request);
}
@Override
public ResponseEntity<String> getHappyBirthday(@ApiParam(value = "Filter by name") @Valid @RequestParam(value = "name", required = false) String name) {
//Request is null!
String accept = request.getHeader("Accept");
if (accept == null || !accept.equals(MediaType.APPLICATION_JSON_VALUE))
throw new UnsupportedMediaTypeException("Accept header must be " + MediaType.APPLICATION_JSON_VALUE);
);
String message = "Happy Birthday " + name;
return new ResponseEntity<>(message, HttpStatus.OK);
}
}
The test class:
public class BirthdayCardsApiControllerTest{
private MockMvc mockMvc;
private final MockHttpServletRequest mockHttpServletRequest = new MockHttpServletRequest();
@InjectMocks
private BirthdayCardsApiController controller;
@Before
public void setUp(){
controller = new BirthdayCardsApiController(new ObjectMapper(), mockHttpServletRequest);
MockitoAnnotations.initMocks(this);
mockMvc = MockMvcBuilders.standaloneSetup(controller).build();
}
@Test
public void getHappyBirthdayTest() throws Exception{
mockMvc.perform(get("/birthday-cards?name=Jack").accept(MediaType.APPLICATION_JSON)).andExpect(status().isOk()).andDo(print());
}
}
Is there a way to share the same HttpServletRequest used by MockMvc and when instantiating the controller under test?