Тестирование MockBean Null - PullRequest
       1

Тестирование MockBean Null

0 голосов
/ 14 декабря 2018

У меня есть это определение класса

@RestController
public class ReservationController {
    @Autowired
    private Reservation reservation;

    @RequestMapping(value = "/reservation", produces = MediaType.APPLICATION_JSON_UTF8_VALUE, method = RequestMethod.POST)
    @ResponseBody
    public Reservation getReservation() {

        return reservation;
    }
}

, где Reservation - это простое Pojo

public class Reservation {
    private long id;
    private String reservationName;

    public Reservation() {
        super();
        this.id = 333;
        this.reservationName = "prova123";
    }

    public Reservation(long id, String reservationName) {
        super();
        this.id = id;
        this.reservationName = reservationName;
    }

    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    public String getReservationName() {
        return reservationName;
    }

    public void setReservationName(String reservationName) {
        this.reservationName = reservationName;
    }

    @Override
    public String toString() {
        return "Reservation [id=" + id + ", reservationName=" + reservationName + "]";
    }
}

, когда я пытаюсь проверить этот класс

@WebMvcTest
@RunWith(SpringRunner.class)
public class MvcTest {
    @Autowired
    private MockMvc mockMvc;

    @MockBean(name = "reservation")
    private Reservation reservation;

    @Test
    public void postReservation() throws Exception {
        mockMvc.perform(MockMvcRequestBuilders.post("/reservation"))
                .andExpect(MockMvcResultMatchers.content().contentType(MediaType.APPLICATION_JSON_UTF8_VALUE))
                .andExpect(MockMvcResultMatchers.status().isOk());
    }
}

Я получилэта ошибка:

org.springframework.web.util.NestedServletException: обработка запроса не удалась;вложенным исключением является org.springframework.http.converter.HttpMessageConversionException: ошибка определения типа: [простой тип, класс org.mockito.internal.debugging.LocationImpl];Вложенное исключение - com.fasterxml.jackson.databind.exc.InvalidDefinitionException: не найден сериализатор для класса org.mockito.internal.debugging.LocationImpl, и не обнаружено никаких свойств для создания BeanSerializer (чтобы избежать исключения, отключите SerializationFeature.FAIL_ON_EMPTY_BEANS) (: spring.boot.usingSpringBoot.entity.Reservation $ MockitoMock $ 980801978 ["mockitoInterceptor"] -> org.mockito.internal.creation.bytebuddy.MockMethodInterceptor ["mockHandler"] -> org.mockito.inoc."] -> org.mockito.internal.stubbing.InvocationContainerImpl [" invocationForStubbing "] -> org.mockito.internal.invocation.InvocationMatcher [" вызов "] -> org.mockito.internal.invocation.InterceptedInvocation [" место "])

.... ....

Причина: com.fasterxml.jackson.databind.exc.InvalidDefinitionException: не найден сериализатор для класса org.mockito.internal.debugging.LocationImplи не найдено никаких свойств для создания BeanSerializer (чтобы избежать исключения, отключите SerializationFeature.FAIL_ON_EMPTY_BEANS) (через цепочку ссылок: spring.boot.usingSpringBoot.entity.Reservation $ MockitoMock $ 980801978 ["mockitoInterceptor"] -> org.mockito.internal.creation.byckorHhod.MerterHud.bytebudhod] -> org.mockito.internal.handler.InvocationNotifierHandler [ "invocationContainer"] -> org.mockito.internal.stubbing.InvocationContainerImpl [ "invocationForStubbing"] -> org.mockito.internal.invocation.InvocationMatcher [ "вызов"] -> org.mockito.internal.invocation.InterceptedInvocation ["location"])

Как правильно ввести резервирование ??

Спасибо

1 Ответ

0 голосов
/ 14 декабря 2018

Вы получаете ошибку, потому что когда вы используете @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());
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...