Spring MockMvc集成测试请求404问题
简单记录一下。刚刚maven工程搭了个项目,准备试试http请求能不能进来。在test目录下写JUnit4代码测试get请求,测试通过表示整个web可以跑起来了。但是MockMvc断言404了。折腾了一会儿一直报404,测试代码如下:
MvcResult mockRes = mockMvc.perform(MockMvcRequestBuilders.get(new URI("/"))) .andExpect(status().isOk()) .andDo(MockMvcResultHandlers.print()) .andReturn();这个代码始终报404,我改成如下:
mockMvc.perform(MockMvcRequestBuilders.get(new URI("/")).accept(MediaType.APPLICATION_JSON).contentType(MediaType.ALL));定义好请求类型是任意响应类型是JSON,结果还是404。搜了一下网络,代码是没问题的。于是不得已tomcat启动去运行,得到正确结果。那么一定是测试代码配置有问题。集成测试是用spring提供的测试包,指定了junit4来测试,并且"@WebAppConfiguration"注解标识是springmvc的测试环境。我往上滚动代码,忽然看到"@ContextConfiguration"注解指定的配置文件写错了,写出了spring容器xml而不是mvc容器,当然测试会产生问题。因为子容器才会加载控制器请求的注解,spring容器独立当然获取不到的。正确代码如下:
@RunWith(SpringJUnit4ClassRunner.class) @WebAppConfiguration //指定mvc子容器xml,而不是spring父容器 @ContextConfiguration("classpath:springmvc.xml") public class EquipmentRecordControllerTest { private MockMvc mockMvc; @Autowired private WebApplicationContext wac; @Before public void beforeSetupTestMock(){ mockMvc = MockMvcBuilders.webAppContextSetup(wac).build(); } @Test public void okTest() throws Exception { MvcResult mockRes = mockMvc.perform(MockMvcRequestBuilders.get(new URI("/"))) .andExpect(status().isOk()) .andDo(MockMvcResultHandlers.print()) .andReturn(); String content = mockRes.getResponse().getContentAsString(); System.out.printf("响应正文:%s%n", content); } }要注意一点是,如果方法不加"@ResponseBody"或控制类不加"@RestController",测试会通过,但响应体是空的,而tomcat会报404,因为没有rest注解返回默认是视图解析,没有对应视图解析模板当然404。另外测试uri一定要正确,且需要"/"路径开头。若设置了Applicants Context的项目名,项目名是不需要加的,否则测试获取到的也是空响应体。如:
//若设置了项目名 不要加起始项目名 //mockMvc.perform(MockMvcRequestBuilders.get(new URI("/webProject/index"))) //is ok: mockMvc.perform(MockMvcRequestBuilders.get(new URI("/index")));另外,若需要测试的代码包含了服务层注解"@Service"等,必须添加父容器spring配置文件,如下:
@ContextConfiguration({"classpath:springmvc.xml", "classpath:spring.xml"})否则会抛出”NoSuchBeanDefinitionException“错误。因为单元测试(准确来说此处测试springweb应为集成测试)没有走web.xml,它不会加载spring配置,单单指定springmvc的配置当然不行了。web.xml中由DispatcherServlet加载mvc,并且设置ContextLoaderListener监听器加载spring,从而设置父子容器关系。单元测试需要模拟web测试环境时,所有都需要显式配置清楚。
来自:Java
更新于2022-09-02 13:42:06 发表于2022-08-31 21:21:20
更新于2022-09-02 13:42:06 发表于2022-08-31 21:21:20
发表您的评论