Spring Boot integration test responding with empty body - MockMvc

12,693

Try with this test. This test is as per spring boot documentation.

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.MOCK)
@AutoConfigureMockMvc
public class ControllerTest {


    @Autowired
    private MockMvc mockMvc;

    @MockBean
    private SearchService service;

    @Before
    public void setUp(){
        when(service.someMethod(any()))
                .thenReturn(SomeResponse);
    }

    @Test
    public void getSearchResults() throws Exception{
        this.mockMvc.perform(post("/something/search").header("header1","1").header("header2","2")
                .content("MY VALID JSON REQUEST HERE")
                .contentType(MediaType.APPLICATION_JSON))
                .andExpect(status().isOk())
                .andDo(mvcResult -> {
                    //Verrify Response here
                });
    }
}
Share:
12,693

Related videos on Youtube

adbar
Author by

adbar

Updated on June 04, 2022

Comments

  • adbar
    adbar almost 2 years

    I've seen similar questions to this, but I've yet to find a solution that works for me, so i'm posting it with hopefully enough details to resolve..

    So I have the following class:

    @RunWith(SpringRunner.class)
    @SpringBootTest
    public class TestController {
    
        @Mock
        private Controller controller;
    
        private MockMvc mockMvc;
    
        @InjectMocks
        private SearchService service;
    
        @Before
        public void setUp(){
            MockitoAnnotations.initMocks(this);
            this.mockMvc = MockMvcBuilders.standaloneSetup(controller).setControllerAdvice(new GlobalExceptionHandler()).build();
        }
    
        @Test
        public void getSearchResults() throws Exception{
            this.mockMvc.perform(post("/something/search").header("header1","1").header("header2","2")
                .content("MY VALID JSON REQUEST HERE")
                .contentType(MediaType.APPLICATION_JSON)).andDo(print());
        }
    }
    

    The above code prints:

    MockHttpServletRequest:
        HTTP Method = POST
        Request URI = /something/search
         Parameters = {}
          Headers = {Content-Type=[application/json], header1=[1], header2=[2]}
    
    Handler:
        Type = com.company.controller.Controller
        Method = public org.springframework.http.ResponseEntity<com.company.SearchResponse> com.company.controller.Controller.getSearchResults(com.company.SearchRequest,java.lang.String,java.lang.String,java.lang.String,java.lang.String,java.lang.String,java.lang.String) throws java.io.IOException
    
    Async:
        Async started = false
         Async result = null
    
    Resolved Exception:
        Type = null
    
    ModelAndView:
        View name = null
        View = null
        Model = null
    
    FlashMap:
        Attributes = null
    
    MockHttpServletResponse:
                Status = 200
         Error Message = null
               Headers = {}
          Content type = null
                  Body = 
         Forwarded URL = null
        Redirected URL = null
               Cookies = []
    

    Even if the data i'm trying to search is not available in my local elastic server (which it is), it should return the body with "{}" not just empty. So i'm a little baffled as to why it's making the connection and returning status 200.

    Here's my controller class:

    @CrossOrigin
    @RestController
    @RequestMapping(value = "/something")
    @Api("search")
    @Path("/something")
    @Produces({"application/json"})
    @Consumes({"application/json"})
    public class Controller {
    
        @Autowired
        private SearchService searchService;
    
        @POST
        @PATH("/search")
        @Consumes({"application/json"})
        @Produces({"application/json"})
        @RequestMapping(value = "/search", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE, consumes MediaType.APPLICATION_JSON_VALUE)
        public ResponseEntity<SearchResponse> getSearchResults(
            @ApiParam(value = "json string with required data", required = true) @Valid @RequestBody SearchRequest request,
            @RequestHeader(required = true) @ApiParam(value = "header1", required = true) @HeaderParam("header1") String header1,
            @RequestHeader(required = true) @ApiParam(value = "header2", required = true) @HeaderParam("header2") String header2
        ) throws IOException {
            //some logic
            return new ResponseEntity(Object, HttpStatus.OK);
        }
    

    Also, if I give some improper values in the request (still proper json), I will receive the valid error responses.. A little peculiar.

    Thanks for anyone who helps!!! :/

  • adbar
    adbar almost 7 years
    gonna try this now. can you link to the spring boot doc you're talking about ?
  • adbar
    adbar almost 7 years
    hey, this actually worked. i just changed .thenReturn() to .thenCallRealMethod()... so it can call the real method.
  • Saurabh Rana
    Saurabh Rana over 2 years
    Can anyone help me understand how ControllerTest will mock Controller we are not using @InjectMocks or anything else that would specify that this test class is for Controller.