Вы получаете ошибку, потому что когда вы используете @MockBean
(или @Mock
в среде, отличной от Spring), вы получаете фиктивный объект Mockito.Этот объект является полым прокси вашего объекта. Прокси имеет те же открытые методы, что и ваш класс, и по умолчанию возвращает значение по умолчанию своего возвращаемого типа (например, null для объектов, 1 для целых и т. Д.) Или ничего не делает для методов void..
Джексон жалуется, потому что ему нужно сериализовать этот прокси, у которого нет полей, а Джексон не знает, что делать.
com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Не найден сериализатор для класса org.mockito.internal.debugging.LocationImpl и не найдены свойства для создания BeanSerializer (во избежание исключения отключите SerializationFeature.FAIL_ON_EMPTY_BEANS
В общем, когда вы высмеиваете зависимость какого-либо классачто вы хотите протестировать, вы издеваетесь над его общедоступными методами, которые используются в тестируемом классе. Непосредственный возврат вашей зависимости не является хорошим вариантом использования в реальном мире - очень маловероятно, что вам придется писать такой код.
Полагаю, вы пытаетесь учиться, поэтому позвольте мнеВозьмите улучшенный пример:
@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
}
}
Вместо непосредственного внедрения объекта-значения у вас обычно есть класс обслуживания, который содержит некоторую бизнес-логику и возвращает что-то - в моем примере ReservationService
, который имеет метод getReservation()
, которыйreturn и объект типа Reservation
.
Имея это, в своем тесте вы можете высмеивать 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());
}
}