Не могу Mockbean HttpServletResponse - PullRequest
0 голосов
/ 19 марта 2019

Я могу использовать @Autowired в контроллере, как

@RestController
public class Index {

    @Autowired
    HttpServletResponse response;

    @GetMapping("/")
    void index() throws IOException {
        response.sendRedirect("http://example.com");
    }
}

это работает;

Но когда я пытаюсь протестировать этот класс, используя @MockBean, как

@RunWith(SpringRunner.class)
@SpringBootTest
public class IndexTest {

    @Autowired
    Index index;

    @MockBean
    HttpServletResponse response;

    @Test
    public void testIndex() throws IOException {
        index.index();
    }
}

выкинуть исключение и сказать

Description:

Field response in com.example.demo.Index required a single bean, but 2 were found:
    - com.sun.proxy.$Proxy69@425d5d46: a programmatically registered singleton  - javax.servlet.http.HttpServletResponse#0: defined in null


Action:

Consider marking one of the beans as @Primary, updating the consumer to accept multiple beans, or using @Qualifier to identify the bean that should be consumed

Как это исправить?

Ответы [ 2 ]

2 голосов
/ 19 марта 2019

Хотя возможно imho, это плохая привычка вводить HttpServletResponse или HttpServletRequest, как это. Это приведет к странным проблемам и выглядит просто странно или неправильно. Вместо этого используйте аргумент метода типа HttpServletResponse и используйте Spring MockHttpServletResponse для тестирования.

Тогда написание модульного теста так же просто, как создание нового экземпляра вашего класса и вызов метода.

public class IndexTest {

    private Index index = new Index();

    @Test
    public void testIndex() throws IOException {
        MockHttpServletResponse response = new MockHttpServletResponse();
        index.index(response);
        // Some assertions on the response. 
    }
}

Если вы хотите протестировать его как часть более крупного интеграционного теста, вы можете сделать то же самое, но использовать аннотацию @WebMvcTest.

@RunWith(SpringRunner.class)
@WebMvcTest(Index.class)
public class IndexTest {

    @Autowired
    private Index index;

    @Test
    public void testIndex() throws IOException {
        MockHttpServletResponse response = new MockHttpServletResponse();
        index.index(response);
        // Some assertions on the response. 
    }
}

Или используйте MockMvc, чтобы проверить его по поддельному запросу

@RunWith(SpringRunner.class)
@WebMvcTest(Index.class)
public class IndexTest {

    @Autowired
    private MockMvc mockMvc;

    @Test
    public void testIndex() throws IOException {
        mockMvc.perform(get("/")).
            andExpect(status().isMovedTemporarily());
        MockHttpServletResponse response = new MockHttpServletResponse();
        index.index(response);
        // Some assertions on the response. 
    }
}

Вышеприведенный тест также можно записать с использованием @SpringBootTest, разница в том, что @WebMvcTest будет только тестировать и загружать веб-фрагмент (т. Е. Материал, связанный с сетью), тогда как @SpringBootTest фактически запустит все приложение.

0 голосов
/ 19 марта 2019

Перво-наперво : Юниты НЕ написаны для контроллера.

Проблемы с кодом-

  1. Либо у вас есть несколько бинов типа Index, либо у вас есть несколько бинов HttpServletResponse. И @Autowired, и @MockBean проверяют по типу, а не по имени.
  2. HttpServletResponse - больше DTO, поэтому его надо смоделировать с помощью @ Mock.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...