【问题标题】:Response data missing in Spring MVC testSpring MVC 测试中缺少响应数据
【发布时间】:2016-06-03 06:06:28
【问题描述】:

我有一个控制器,它像这样写入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;行号:1;列号: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 的引用? 编辑我需要触发视图来渲染模型吗?

【问题讨论】:

  • 它在http请求对象的范围内,我可以看到它的属性。属性不是响应正文的一部分。响应将由“数据集/创建”视图创建。请检查此视图返回给客户端的内容。
  • 显示您尝试传递的 xml。错误是在尝试传递 xml 时。仅仅因为它在浏览器中打开并不意味着它是有效的 xml。它会解释任何东西。
  • 您的设置如何? getDataset 不返回数据,而是返回视图的名称。您需要完整的集成测试才能获得实际响应。
  • @Braj 好的,你明白了,控制器实际上返回“成功”。我承认我正在从其他人那里接管这段代码,但我真的不知道它应该如何工作。 AFAIK 没有“成功”视图,但是在我的mvc-dispatcher-servlet.xml 中配置了defaultViews,其中一个是带有Jaxb2Marshallerxml.MarshallingView,它指向一个装满javax.xml 注释的bean 的包,例如作为DatasetResponse
  • @Pri 你是对的,浏览器中没有显示 XML 声明。但从例外情况来看,我很确定测试中的文档实际上是空的(另请参见打印输出中的Body = )。 @zero,那么如何设置完整的集成测试?如果我将控制器更改为使用@RestController 而不是@Controller,并返回DatasetResponse 而不是String,则响应正文包含正确的文档并且xpath 测试有效。但是 ModelAndView 是空的,andExpect(model() 行失败。

标签: spring unit-testing spring-mvc


【解决方案1】:

这归结为测试配置错误:我的 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");

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-07
    • 1970-01-01
    • 2021-01-07
    • 1970-01-01
    相关资源
    最近更新 更多