在集成测试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将所有对象字段附加为。参数使用反射或单独用于每个测试用例。。
我不知道,感觉不直观。。
有什么想法/想法可以让我的爱好变得更容易吗?(除了直接呼叫控制器)
谢谢
我相信我已经找到了使用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());
}
}
与MockMvc集成测试的主要目的之一是验证模型对象是否正确填充了表单数据。
为了做到这一点,您必须传递从实际表单传递的表单数据(使用.参数()
)。如果您使用从NewObject
到数据的自动转换,您的测试将不会涵盖特定类别的可能问题(修改NewObject
与实际表单不兼容)。
我有同样的问题,结果证明,通过使用JSON marshaller,解决方案相当简单
让您的控制器通过将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);
}
}
我遵循了http://viralpatel.net/blogs/spring-mvc-multi-row-submit-java-list/将对象列表发布到我的Spring Controller。很快,当列表大小达到256时,我遇到了IndexOutOfBoundsException。 我找到了一个答案,它说在WebDataBinder中设置setAuto就可以解决这个问题。所以在我的控制器中,我
我有一个复选框的集合,每个复选框代表一个“产品”的顶部。我想传递一个修改的产品对象,勾选的浇头存储为selectedToppings。 我已经尝试了下面的代码,但不起作用。问题是我正在传递一个空的“product”对象,并且只存储复选框值(作为“selectedToppings”)。如何将“product”对象与“selectedToppings”一起传递? html(片段): 控制器: 实体:
当使用mockito单元测试Spring mvc控制器时,如何注入道层对象。当使用SpringJUnit4ClassRunner类时,它总是使用@Spy注释给空指针异常。 示例代码: 在这个测试用例中,依次调用,它总是返回
问题内容: 我有一个定义了POST处理程序的控制器,如下所示: 以JSON格式查看时,UIVendor对象如下所示: UIVendor bean具有一个ArrayList类型的名为“ Emails”的字段,带有适当的设置器和获取器(getEmails / setEmails)。NotificationEmail对象也具有适当的公共设置器/获取器。 当我尝试使用以下代码发布对象时: 我在日志中收到此
我的视图中有一个向控制器发送对象的表单,但问题是,如果我发送的对象超过256个,就会出现异常: 所以我在想为什么会有这样的限制,于是我找到了这个话题:https://stackoverflow.com/a/24699008/4173394 但它似乎对我不起作用(可能是我的一个坏习惯)。 下面是我的结构:我的视图名为createUpdate.vm,并像这样发布我的表单: 我在FollowerFile
我有窗体和相应的控制器,对象列表被传递给它们。 实体类: 控制器: 形式: 我假设表单中的百里叶th:each循环变量不能是th:object=${ent2}(因为如果我这样做,select form返回null)。而th:value="${ent2.name}返回字符串值。所以我不得不将@RequestParam(th:value)发送给“save”方法。但是在这种情况下,我必须对数据库进行额外