Fixing Pageable Errors in JUnit MockMvc Tests
If you’ve tried unit testing a Spring controller that accepts a Pageable
parameter using JUnit 5 and Mockito with MockMvc
, you might have encountered this error:
java.lang.IllegalStateException: No primary or single unique constructor found for interface org.springframework.data.domain.Pageable
This happens because, in a standalone MockMvc
test (without loading the full Spring context), Spring doesn’t automatically know how to convert query parameters like page
, size
, and sort
into a Pageable
object. Without the proper resolver, it tries to instantiate Pageable
directly, which fails because it’s an interface.
The solution is simple, manually register the PageableHandlerMethodArgumentResolver
when building your MockMvc
instance.
@BeforeEach
void setUp() {
mockMvc = MockMvcBuilders.standaloneSetup(ticketController)
.setCustomArgumentResolvers(new PageableHandlerMethodArgumentResolver())
.build();
}
Then, in your test, you can pass query parameters as usual:
@Test
void testFilter() throws Exception {
...
mockMvc.perform(get("/v1/api/tickets" + "/filter")
.parma("page", "0")
.param("size", "5"))
.andExpect(status().is2xxSuccessful());
...
}
With this setup, your Pageable
arguments will work just like in a real Spring application, and your tests will no longer throw the IllegalStateException
.
Thanks for reading! If you have any questions or run into other issues with MockMvc
and Pageable
, feel free to reach out. I’d be happy to help.