jUnit: No primary or default constructor found for

2019-07-15 08:53发布

问题:

I have a restcontroller inside a spring-application returning a list of objects...

@GetMapping
@Override
public ResponseEntity readAll(@QuerydslPredicate(root = Entity.class) Predicate predicate, Pageable pageable){
    ...
}

If I run it, everything works fine. I can filter the request by pageable and predicate. But if I run the junit test, it fails...

@Test
public void readAllTest(){
MockMvcBuilders.standaloneSetup(*myController*)
            .build().perform(MockMvcRequestBuilders.get(*myUri*)
                    .accept(MediaType.APPLICATION_JSON_UTF8_VALUE)
            )
            .andExpect(status().isOk())
            .andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8_VALUE));
}

Getting the following Errormessage... org.springframework.web.util.NestedServletException: Request processing failed; nested exception is java.lang.IllegalStateException: No primary or default constructor found for interface com.querydsl.core.types.Predicate

Does anybody know how to test a restcontroller with a Pageable and Predicate?

回答1:

  1. Try to add on your test class annotation @Import(QuerydslWebConfiguration.class). It adds controller argument resolver for com.querydsl.core.types.Predicate into spring context.

  2. But after you'll face with an exception like:

    No primary or default constructor found for interface org.springframework.data.domain.Pageable.

  3. There is annotation, loads argument resolvers for both these interfaces. org.springframework.data.web.config.EnableSpringDataWebSupport

Addapted for your test class:

@RunWith(SpringRunner.class)
@WebMvcTest(*myController*.class)
@EnableSpringDataWebSupport
public class ControllerTest{

  @Test
  public void readAllTest(){
    MockMvcBuilders.standaloneSetup(*myController*)
            .build().perform(MockMvcRequestBuilders.get(*myUri*)
                    .accept(MediaType.APPLICATION_JSON_UTF8_VALUE)
            )
            .andExpect(status().isOk())
            .andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8_VALUE));
  }
}


回答2:

For now, you just need to setup mockMvc with ApplicationContext, like

@RunWith(SpringRunner.class)
@SpringBootTest
public class ControllerTest {

  @Autowired
  private WebApplicationContext webApplicationContext;

  @Test
  public void readAllTest() throws Exception {
    MockMvcBuilders.webAppContextSetup(this.webApplicationContext).build()
        .perform(MockMvcRequestBuilders.get("YOUR_URI")
        .accept(MediaType.APPLICATION_JSON_UTF8_VALUE))
        .andExpect(status().isOk())
        .andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8_VALUE));
  }

}

https://docs.spring.io/spring/docs/current/spring-framework-reference/testing.html#spring-mvc-test-server