首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >集成测试将整个对象POSTing到Spring MVC控制器

集成测试将整个对象POSTing到Spring MVC控制器
EN

Stack Overflow用户
提问于 2013-06-17 16:17:29
回答 8查看 115.7K关注 0票数 61

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

代码语言:javascript
复制
mockMvc.perform(post("/somehwere/new").param("items[0].value","value"));

这对于小表单来说是很好的。但是如果我发布的对象变得更大了呢?此外,如果我只发布整个对象,它会使测试代码看起来更好。

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

我们使用了spring 3.2.2,其中包含了spring-test-mvc。

我的表单模型如下所示:

代码语言:javascript
复制
NewObject {
    List<Item> selection;
}

我试过这样的电话:

代码语言:javascript
复制
mockMvc.perform(post("/somehwere/new").requestAttr("newObject", newObject) 

这样的控制器:

代码语言:javascript
复制
@Controller
@RequestMapping(value = "/somewhere/new")
public class SomewhereController {

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

但是对象将是空的(是的,我以前在测试中填充过它)

我找到的唯一有效的解决方案是像这样使用@SessionAttribute:Integration Testing of Spring MVC Applications: Forms

但是我不喜欢在我需要的每个控制器的末尾都要记得调用complete的想法。在所有表单数据不必在会话中之后,我只需要为一个请求提供这些数据。

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

我不知道,感觉很不直观..

有什么想法/想法可以让我的点赞变得更容易吗?(除了直接调用控制器之外)

谢谢!

EN

回答 8

Stack Overflow用户

回答已采纳

发布于 2013-06-17 16:50:34

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

为了做到这一点,你必须传递表单数据,因为它们是从实际表单传递过来的(使用.param())。如果您使用某种从NewObject到from数据的自动转换,那么您的测试将不会涵盖特定类别的可能问题(对NewObject的修改与实际表单不兼容)。

票数 27
EN

Stack Overflow用户

发布于 2014-08-04 18:33:55

我也有同样的问题,结果证明解决方案相当简单,只需使用JSON编组程序。

让您的控制器只需通过将@ModelAttribute("newObject")更改为@RequestBody来更改签名。如下所示:

代码语言:javascript
复制
@Controller
@RequestMapping(value = "/somewhere/new")
public class SomewhereController {

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

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

代码语言:javascript
复制
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方法只是:

代码语言:javascript
复制
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);
    }
}  
票数 69
EN

Stack Overflow用户

发布于 2016-08-04 21:34:26

我相信我使用Spring Boot 1.4得到了最简单的答案,包括测试类的导入:

代码语言:javascript
复制
public class SomeClass {  /// this goes in it's own file
//// fields go here
}

import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest
import org.springframework.http.MediaType
import org.springframework.test.context.junit4.SpringRunner
import org.springframework.test.web.servlet.MockMvc

import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status

@RunWith(SpringRunner.class)
@WebMvcTest(SomeController.class)
public class ControllerTest {

  @Autowired private MockMvc mvc;
  @Autowired private ObjectMapper mapper;

  private SomeClass someClass;  //this could be Autowired
                                //, initialized in the test method
                                //, or created in setup block
  @Before
  public void setup() {
    someClass = new SomeClass(); 
  }

  @Test
  public void postTest() {
    String json = mapper.writeValueAsString(someClass);
    mvc.perform(post("/someControllerUrl")
       .contentType(MediaType.APPLICATION_JSON)
       .content(json)
       .accept(MediaType.APPLICATION_JSON))
       .andExpect(status().isOk());
  }

}
票数 22
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17143116

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档