SpringMVC 测试框架 MockMvc 天坑一枚
SpringMVC 测试框架 MockMvc 天坑一枚
打雷要下雨LEO 发表于1年前
SpringMVC 测试框架 MockMvc 天坑一枚
  • 发表于 1年前
  • 阅读 651
  • 收藏 3
  • 点赞 0
  • 评论 0

腾讯云 技术升级10大核心产品年终让利>>>   

最近使用SpringMvc写一个URL比较复杂的RequestMapping,最后使用MockMvc测试下URL。

出现的问题是根本不存在的URI,居然返回200。使用以下代码测试:

 

@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@ContextConfiguration({
        "classpath:spring/spring-web.xml"
})
public class SearchControllerTest {
    @Autowired
    private WebApplicationContext wac;
    private MockMvc mockMvc;

    @Before
    public void setUp() throws Exception {
        this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
    }

    @Test
    public void testURLMapping() throws Exception {
        String[] testCase= {
            "/asdf"    // 根本不存在
        };
        for (String url : testCase) {
            this.mockMvc.perform(MockMvcRequestBuilders.get(url))
                    .andDo(MockMvcResultHandlers.print())  // 输出信息
                    .andExpect(MockMvcResultMatchers.status().isOk());

        }
    }
}

测试通过,但是项目跑起来浏览器看HTTP请求返回的是404,输出的信息如下:

MockHttpServletRequest:
      HTTP Method = GET
      Request URI = /asdf
       Parameters = {}
          Headers = {}

Handler:
             Type = org.springframework.web.servlet.resource.DefaultServletHttpRequestHandler

Async:
    Async started = false
     Async result = null

Resolved Exception:
             Type = null

ModelAndView:
        View name = null
             View = null
            Model = null

FlashMap:
       Attributes = null

MockHttpServletResponse:
           Status = 200  // 200!
    Error message = null
          Headers = {}
     Content type = null
             Body = 
    Forwarded URL = default  // 问题的关键!
   Redirected URL = null
          Cookies = []

问题的关键就是Forward那里,这个问题三年前有人反馈过了(https://jira.spring.io/browse/SPR-10695)。

具体原因:

内部进行URL匹配未找到会重定向到default setvlet再返回404错误,这个重定向是在Tomcat内部完成的,客户端是察觉不到的。SpringMvc作为一个servlet可以看责任链模式上的一棒,这个不匹配的请求其实和CSS、Js等静态文件一样最后传递给了Tomcat的default,最终是Tomcat抛出的404错误。MockMvc毕竟不是模拟浏览器访问,MockMvc并不能发现404错误,以上是我个人的理解,推荐看一下上面的链接。

改进办法:

MockMvc并不知道不匹配的请求最后Tomcat怎样处理的,但是可以知道这个请求是在Spring内完成的还是最后做了重定向。修改成如下测试代码:

this.mockMvc.perform(MockMvcRequestBuilders.get(url))
        .andDo(MockMvcResultHandlers.print())
        .andExpect(MockMvcResultMatchers.status().isOk())
        .andExpect(forwardedUrl(null));

完成!

标签: MockMvc SpringMVC
共有 人打赏支持
粉丝 10
博文 14
码字总数 4690
×
打雷要下雨LEO
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
* 金额(元)
¥1 ¥5 ¥10 ¥20 其他金额
打赏人
留言
* 支付类型
微信扫码支付
打赏金额:
已支付成功
打赏金额: