Spring MVC测试中缺少响应数据

时间:2016-06-03 06:06:28

标签: spring unit-testing spring-mvc

我有一个写入ModelMap的控制器,如下所示:

@Controller
@RequestMapping("/dataset")
public class DatasetController {

    @Autowired
    DatasetDao datasetDao;

    @RequestMapping(method = RequestMethod.GET)
    public String getDataset(@RequestParam String name, ModelMap model) {
        Dataset ds = datasetDao.get(name);
        model.addAttribute("response", new DatasetResponse(ds));
        return "Success";
    }

我想编写一个获取数据集的测试用例,然后根据其内容执行更多操作。但是,我无法从服务中获取数据。到目前为止我的测试用例是:

@Test
public void testProducesXml() throws Exception {
    mockMvc.perform(get("/dataset.xml").param("name", "foo"))
        .andDo(print())
        .andExpect(status().isOk())
        .andExpect(model().attribute("Response",
            hasProperty("name", is("foo"))))
        .andExpect(xpath("/dataset/name").string("foo"));
}

model().attribute行已通过,但测试在xpath处失败:

  

org.xml.sax.SAXParseException; lineNumber:1; columnNumber:1;提前结束。

最终我想在我的测试函数中获得DatasetResponse的副本,以便我可以用它做其他事情。我尝试使用andReturn(),但由于xpath失败的原因相同而失败。

事实证明,即使模型中有DatasetResponse,响应的主体也是空的:

ModelAndView:
    View name = Success
         View = null
    Attribute = Response
        value = org.vpac.web.model.response.DatasetResponse@457fdd58
       errors = []

MockHttpServletResponse:
       Status = 200
Error message = null
      Headers = {}
 Content type = null
         Body = 

但是,如果我在Tomcat中启动应用程序并在浏览器中转到/dataset.xml?name=foo,我可以将数据视为XML。

那么,为什么身体是空的,我怎样才能获得对DatasetResponse的引用? 编辑我是否需要触发视图来渲染模型或什么?

1 个答案:

答案 0 :(得分:0)

这归结为测试配置错误:我的MVC配置分为两个文件,如web.xml文件中所述:

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>
        /WEB-INF/mvc-dispatcher-servlet.xml 
        /WEB-INF/applicationContext.xml
    </param-value>
</context-param>

但是根据其他地方的例子,我只用我的测试类注释:

@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@ContextConfiguration("file:src/main/webapp/WEB-INF/applicationContext.xml")
@Transactional
public class DatasetTest {
    ...

添加缺少的mvc-dispatcher-servlet.xml可解决问题:

@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@ContextConfiguration({
    "file:src/main/webapp/WEB-INF/mvc-dispatcher-servlet.xml",
    "file:src/main/webapp/WEB-INF/applicationContext.xml"})
@Transactional
public class DatasetTest {
    ...

现在ModelAndView包含我从控制器返回的对象,并且响应的主体不为空。 .andExpect(xpath按预期工作,我可以使用以下命令获取响应对象的副本:

mockMvc.perform(...).andReturn().getModelAndView().getModel().get("Response");