我可以在控制器中使用@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
如何解决?
答案 0 :(得分:2)
尽管可能存在恕我直言,但这是注入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
仅测试和引导Web切片(即与Web相关的东西),而@SpringBootTest
实际上将启动整个应用程序
答案 1 :(得分:0)
第一件事:没有为控制器编写Junit。
发出代码-
Index
类型的bean,或者您有多个HttpServletResponse
类型的bean。 @Autowired
和@MockBean
均按类型而不是名称进行检查。HttpServletResponse
是DTO的更多内容,因此应使用@Mock对其进行模拟。