我正在测试Spring MVC @RestController
,后者又调用外部REST服务。我使用MockMvc
来模拟弹簧环境,但我希望我的控制器能够真正调用外部服务。手动测试RestController工作正常(使用Postman等)。
我发现如果我以特定的方式设置测试,我会得到一个完全空的响应(状态代码除外):
@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@ContextConfiguration(classes = AnywhereController.class)
public class AnywhereControllerTest{
@Autowired
private AnywhereController ac;
@Autowired
private WebApplicationContext wac;
private MockMvc mockMvc;
@Before
public void setup() {
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
}
@Test
public void testGetLocations() throws Exception {
...
MvcResult result = mockMvc.perform(MockMvcRequestBuilders.get("/anywhere/locations").accept(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andExpect(content().string(containsString("locations")))
.andExpect(content().contentTypeCompatibleWith(MediaType.APPLICATION_JSON));
.andReturn();
}
测试失败,因为内容和标题为空。然后我尝试将其添加到测试类中:
@Configuration
@EnableWebMvc
public static class TestConfiguration{
@Bean
public AnywhereController anywhereController(){
return new AnywhereController();
}
}
另外我改变了ContextConfiguration
注释(尽管我想知道它实际上是做什么的):
@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@ContextConfiguration
public class AnywhereControllerTest{...}
现在突然所有的检查都成功了,在打印内容正文时我得到了所有的内容。
这里发生了什么?这两种方法有什么区别?
答案 0 :(得分:2)
评论中有人提到了@EnableWebMvc,结果证明这是正确的领导。 我没有使用@EnableWebMvc因此
如果您不使用此注释,您最初可能不会注意到任何差异,但内容类型和接受标题之类的内容通常不会起作用。 Source
我对框架内部工作原理的了解有限,但在启动过程中发出的简单警告可能会节省大量的调试时间。当人们使用@Configuration和/或@RestController他们也想使用@EnableWebMvc(或它的xml版本)时,机会很高。
更糟糕的是,Spring Boot会自动添加这个注释,这就是为什么互联网上的许多教程(也是官方教程)都没有提到@EnableWebMvc。