Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Testing rest controller with PageableDefault

Im trying to test a rest service that has @getmapping one param and PageableDefault

   @GetMapping(path = "/api/{serial}/gender")
    public ResponseEntity<?> task(
        @PathVariable(value = "serial") String Serial,
        @PageableDefault(size = 5, value = 0) Pageable pageable) {
    return ResponseEntity.ok(page);
}

The test suite its with mockmvc

@Test
public void testTask() throws Exception {
 String url ="/api/123456789/gender";
    MvcResult mvcResult = mockMvc.perform(MockMvcRequestBuilders.get(url))
           .andExpect(MockMvcResultMatchers.status().isOk()).andReturn();
}

I got the following error , im unable to inject Pageable cause its a interface how can i mock the @pageable default ?

org.springframework.web.util.NestedServletException: Request processing failed; nested exception is java.lang.IllegalStateException: No primary or default constructor found for interface org.springframework.data.domain.Pageable

like image 915
Guillermo Nahuel Varelli Avatar asked Jul 02 '18 02:07

Guillermo Nahuel Varelli


2 Answers

Guilhermo,

Try this piece of code :

mockMvc = MockMvcBuilders.standaloneSetup(controller)
   .setCustomArgumentResolvers(new PageableHandlerMethodArgumentResolver())
   .setViewResolvers(new ViewResolver() {
       @Override
       public View resolveViewName(String viewName, Locale locale) throws Exception {
          return new MappingJackson2JsonView();
      }
   })
   .build();

See this post for further information: Isolated Controller Test can't instantiate Pageable

Best regards!

like image 196
ACMattos Avatar answered Nov 08 '22 06:11

ACMattos


Pageable in test can cause some trouble especially when you using some additional tools like swagger or local data base only for tasting like H2.

First of all we must add controller which we want to test:

@Autowired
private TestingController testingController;

Simple test for controller without Pagable can look like this:

    given().contentType(ContentType.JSON).log().all().
        standaloneSetup(testingController).
        body(new RequestObjectExample()).
        when().
        post("/someUrl?page=0&size=10,asc").
        then().statusCode(200);

and simple test for controller with Pagable can look like this:

    StandaloneMockMvcBuilder standaloneMockMvcBuilder = MockMvcBuilders.standaloneSetup(testingController)
        .setCustomArgumentResolvers(pageableArgumentResolver);

    given().contentType(ContentType.JSON).log().all().
        standaloneSetup(standaloneMockMvcBuilder).
        body(new RequestObjectExample()).
        when().
        post("/someUrl?page=0&size=10,asc").
        then().statusCode(200);

P.S. to get pageableArgumentResolver just import PageableHandlerMethodArgumentResolver and inject it in class:

import org.springframework.data.web.PageableHandlerMethodArgumentResolver;

@Inject
    private PageableHandlerMethodArgumentResolver pageableArgumentResolver;
like image 1
Witold Krzemiński Avatar answered Nov 08 '22 06:11

Witold Krzemiński