I have this class definition
@RestController
public class ReservationController {
@Autowired
private Reservation reservation;
@RequestMapping(val
You're getting the error because when you use @MockBean
(or @Mock
in a non Spring environment) you get a Mockito mock object. This object is a hollow proxy of your object.The proxy has the same public methods as your class and by default return the default value of it's return type (e.g. null for objects, 1 for ints, etc.) or does nothing for void methods.
Jackson is complaining because it has to serialize this proxy that has no fields and Jackson does not know what to do.
com.fasterxml.jackson.databind.exc.InvalidDefinitionException: No serializer found for class org.mockito.internal.debugging.LocationImpl and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS
In general when you mock a dependency of some class that you want to test, you mock it's public methods, that are used in the class that you test. Directly returning your dependency is not a good real world use case - it's very unlikely that you will have to write a code like this.
I guess you're trying to learn so let me provide an improved example:
@RestController
public class ReservationController {
@Autowired
private ReservationService reservationService; //my chnage here
@RequestMapping(value = "/reservation", produces = MediaType.APPLICATION_JSON_UTF8_VALUE, method = RequestMethod.POST)
@ResponseBody
public Reservation getReservation() {
return reservationService.getReservation(); //my chnage here
}
}
Instead of directly injecting a value object you usually have a service class that contain some business logic and return something - in my example ReservationService
which have a method getReservation()
that return and object of type Reservation
.
Having that, in your test you can mock the ReservationService
.
@WebMvcTest
@RunWith(SpringRunner.class)
public class MvcTest {
@Autowired
private MockMvc mockMvc;
@MockBean(name = "reservation")
private ReservationService reservationService; //my chnage here
@Test
public void postReservation() throws Exception {
// You need that to specify what should your mock return when getReservation() is called. Without it you will get null
when(reservationService.getReservation()).thenReturn(new Reservation()); //my chnage here
mockMvc.perform(MockMvcRequestBuilders.post("/reservation"))
.andExpect(MockMvcResultMatchers.content().contentType(MediaType.APPLICATION_JSON_UTF8_VALUE))
.andExpect(MockMvcResultMatchers.status().isOk());
}
}