Spring MockMvc集成测试请求404问题

·Spring ·单元测试

简单记录一下。刚刚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


发表您的评论





公元2024年甲辰龍年,平安健康、龍行天下!