集成测试将整个对象发布到 Spring MVC 控制器

新手上路,请多包涵

在集成测试 spring mvc web 应用程序时,有没有办法根据模拟请求传递整个表单对象?我所能找到的就是将每个字段作为参数单独传递,如下所示:

 mockMvc.perform(post("/somehwere/new").param("items[0].value","value"));

这对小形式很好。但是,如果我发布的对象变大了怎么办?如果我可以只发布整个对象,它也会使测试代码看起来更好。

具体来说,我想通过复选框测试多个项目的选择,然后发布它们。当然我可以测试发布单个项目,但我想知道..

我们正在使用包含 spring-test-mvc 的 spring 3.2.2。

我的表单模型看起来像这样:

 NewObject {
    List<Item> selection;
}

我试过这样的电话:

 mockMvc.perform(post("/somehwere/new").requestAttr("newObject", newObject)

像这样的控制器:

 @Controller
@RequestMapping(value = "/somewhere/new")
public class SomewhereController {

    @RequestMapping(method = RequestMethod.POST)
    public String post(
            @ModelAttribute("newObject") NewObject newObject) {
        // ...
    }

但是该对象将是空的(是的,我之前在测试中已经将其填充)

我发现唯一可行的解决方案是像这样使用 @SessionAttribute: Spring MVC 应用程序的集成测试:表单

但是我不喜欢必须记住在我需要它的每个控制器的末尾调用 complete 的想法。毕竟表单数据不必在会话中,我只需要一个请求。

所以我现在唯一能想到的就是编写一些 Util 类,它使用 MockHttpServletRequestBuilder 将所有对象字段附加为 .param 使用反射或为每个测试用例单独附加..

不知道,感觉不直观。。

关于如何让我的喜欢更容易的任何想法/想法? (除了直接调用控制器)

谢谢!

原文由 Pete 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 532
2 个回答

使用 MockMvc 进行集成测试的主要目的之一是验证模型对象是否正确填充了表单数据。

为此,您必须传递从实际表单传递的表单数据(使用 .param() )。如果您使用从 NewObject 到数据的一些自动转换,您的测试将不会涵盖特定类别的可能问题(修改 NewObject 与实际形式不兼容)。

原文由 axtavt 发布,翻译遵循 CC BY-SA 3.0 许可协议

我有同样的问题,结果证明解决方案相当简单,通过使用 JSON 编组器。

让您的控制器通过将 @ModelAttribute("newObject") @RequestBody 更改签名。像这样:

 @Controller
@RequestMapping(value = "/somewhere/new")
public class SomewhereController {

    @RequestMapping(method = RequestMethod.POST)
    public String post(@RequestBody NewObject newObject) {
        // ...
    }
}

然后在你的测试中你可以简单地说:

 NewObject newObjectInstance = new NewObject();
// setting fields for the NewObject

mockMvc.perform(MockMvcRequestBuilders.post(uri)
  .content(asJsonString(newObjectInstance))
  .contentType(MediaType.APPLICATION_JSON)
  .accept(MediaType.APPLICATION_JSON));

其中 asJsonString 方法只是:

 public static String asJsonString(final Object obj) {
    try {
        final ObjectMapper mapper = new ObjectMapper();
        final String jsonContent = mapper.writeValueAsString(obj);
        return jsonContent;
    } catch (Exception e) {
        throw new RuntimeException(e);
    }
}

原文由 nyxz 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题