Spring Boot Unit Test с @WebMvcTest - выполнение не переходит на уровень обслуживания из контроллера и возвращает null без ошибок

Я пишу модульный тест для контроллера своего весеннего загрузочного приложения. У меня есть типичные классы MVC: ObjectSchemaController, ObjectSchemaService и ObjectSchemaDao. Я написал модульный тест с помощью @WebMvcTest и издевался над своим сервисом и классом dao с помощью @MockBean. (следуя этому руководству: https://www.baeldung.com/spring-boot-testing)

Ниже мой модульный тест:

@RunWith(SpringRunner.class)
@WebMvcTest(ObjectSchemaController.class)
public class ObjectSchemaControllerTest2 {
    @Autowired
    private MockMvc mvc;
    @MockBean
    private ObjectSchemaService service;
    @MockBean
    private ObjectSchemaDao dao;
    @Autowired
    ObjectMapper objectMapper;
    @Test
    public void testCreateObjectSchemaPass() throws Exception {
        String payload = "{\"some_key\":\"some val\"}";
        ObjectSchema objectSchema = objectMapper.readValue(payload, ObjectSchema.class);

        Mockito.when(service.createSchema(objectSchema))
        .thenReturn(objectSchema);
        Mockito.when(dao.createSchema(objectSchema)).thenReturn(objectSchema);

        mvc.perform(MockMvcRequestBuilders.post("/objectservice/schema/")
       .contentType("application/json")
       .content(objectMapper.writeValueAsString(objectSchema)))
       .andExpect(status().isOk());
    }

}

ниже мой класс обслуживания:

@Service
public class ObjectSchemaService {
    @Autowired
    ObjectSchemaDao objectSchemaDao;

    public ObjectSchema createSchema(@Valid ObjectSchema objectSchema)throws Exception {
        return objectSchemaDao.createSchema(objectSchema);
    }
}

Проблема, с которой я сталкиваюсь с модульным тестом, заключается в том, что уровень обслуживания не выполняется и возвращает нулевое значение.

Когда я отлаживаю, я вижу, что выполнение в моем классе контроллера и ObjectSchemaService выглядит как имитация в контроллере. Но выполнение никогда не происходит на уровне обслуживания, и значение, возвращаемое методом службы, равно нулю.

Я сослался на другие руководства - они делают аналогичные шаги. Но у меня это не работает. Что мне здесь не хватает?

Я также видел этот пост с аналогичной проблемой.

POST модульного теста с @WebMvcTest - служба @MockBean возвращает значение null

Я убедился, что входные объекты как для моего фактического контроллера, так и для того, который я передаю в модуле, являются экземплярами одного и того же класса.


person FurElise    schedule 29.03.2019    source источник


Ответы (2)


Вы издеваетесь над ObjectSchemaService, но никакого поведения не ожидается. Вам необходимо настроить поведение для имитируемых сервисов. Так что в зависимости от сигнатуры метода и результата что-то вроде.

Mockito.when(service.createSchema(Mockito.any(ObjectSchema.class)).thenReturn(objectSchema);

На данный момент макет ObjectSchemaService просто возвращает значение по умолчанию, которое в вашем случае является нулевым.

Чтобы быть прозрачными и ненавязчивыми, все mockito mock'ы по умолчанию возвращают "хорошие" значения. Например: нули, ложные значения, пустые коллекции или нули.

Если вы обновите свой ответ подробностями для ObjectSchemaService, я также могу обновить свой ответ.

person brass monkey    schedule 29.03.2019
comment
Спасибо за ответ. Я пробовал с Mockito.when (обновлен и в моем вопросе). Но все та же проблема. служба возвращает ноль. - person FurElise; 29.03.2019
comment
Благодарность! Mockito.any (ObjectSchema.class) был недостающим элементом - person FurElise; 29.03.2019

Вы имитируете ObjectSchemaService, поэтому вам нужно сообщить службе, как имитировать значения из службы при вызове метода. Если вы не насмехаетесь над значениями службы, Mockito не знает, что они должны возвращать, всегда возвращайте значение null. В этом тесте имитировать ObjectSchemaDao не нужно.

Примечание: я использую Lombok в коде как ObjectSchema.builder (), чтобы вернуть объект с идентификатором, когда он хранится в базе данных, вы можете использовать конструктор. Предполагая, что служба вернет объект.

Код выглядит так:

import static org.mockito.BDDMockito.given;

@Test
public void testCreateObjectSchemaPass() throws Exception {
        String payload = "{\"some_key\":\"some val\"}";
        ObjectSchema objectSchema = objectMapper.readValue(payload, ObjectSchema.class);
        given(service.createSchema(objectSchema)).willReturn(
                ObjectSchema.builder()
                        .id(1)
                        .someKey("Some Val")
                        .build());
        mvc.perform(MockMvcRequestBuilders.post("/objectservice/schema/").contentType("application/json").content(objectMapper.writeValueAsString(objectSchema)))
                .andExpect(status().isOk());
    }
person Juan David    schedule 29.03.2019