在集成测试spring mvc web应用时,有没有办法在模拟请求中传递整个表单对象?我所能找到的就是将每个字段分别作为一个参数传递,如下所示:
mockMvc.perform(post("/somehwere/new").param("items[0].value","value"));这对于小表单来说是很好的。但是如果我发布的对象变得更大了呢?此外,如果我只发布整个对象,它会使测试代码看起来更好。
具体地说,我想通过复选框来测试多个项目的选择,然后发布它们。当然,我可以只测试发布一个项目,但我想知道..
我们使用了spring 3.2.2,其中包含了spring-test-mvc。
我的表单模型如下所示:
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:Integration Testing of Spring MVC Applications: Forms
但是我不喜欢在我需要的每个控制器的末尾都要记得调用complete的想法。在所有表单数据不必在会话中之后,我只需要为一个请求提供这些数据。
因此,我现在唯一能想到的就是编写一些Util类,它使用MockHttpServletRequestBuilder将所有对象字段附加为.param,使用反射,或者为每个测试用例单独添加。
我不知道,感觉很不直观..
有什么想法/想法可以让我的点赞变得更容易吗?(除了直接调用控制器之外)
谢谢!
发布于 2013-06-17 16:50:34
使用MockMvc进行集成测试的主要目的之一是验证模型对象是否正确填充了表单数据。
为了做到这一点,你必须传递表单数据,因为它们是从实际表单传递过来的(使用.param())。如果您使用某种从NewObject到from数据的自动转换,那么您的测试将不会涵盖特定类别的可能问题(对NewObject的修改与实际表单不兼容)。
发布于 2014-08-04 18:33:55
我也有同样的问题,结果证明解决方案相当简单,只需使用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);
}
} 发布于 2016-08-04 21:34:26
我相信我使用Spring Boot 1.4得到了最简单的答案,包括测试类的导入:
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());
}
}https://stackoverflow.com/questions/17143116
复制相似问题