How do I test form submission with Spring MVC test?

Psy*_*nch 2 groovy spring spring-mvc spring-test-mvc thymeleaf

Most of my experience with creating controllers with Spring are for REST controllers that consume JSON formatted requests. I've been searching for documentation on how to do testing for form submission, and so far this is how I understand it should go using MockMvc:

MvcResult result = mockMvc.perform(post("/submit")
                .param('title', 'test title')
                .param('description', 'test description'))
                .andReturn()
Run Code Online (Sandbox Code Playgroud)

However, I'm not sure how to map the form parameters to a model object. I've seen the @ModelAttribute annotation pop up in my searches but I can't figure out how it should be used for mapping. In addition, this quick start guide from the official documentation does not elaborate on how things like th:object and th:field translate to HTML and subsequently to URL encoded form.

I have my controller code similar to the following:

@PostMapping('/submit')
def submit(@ModelAttribute WriteUp writeUp) {
    //do something with writeUp object
    'result'
}
Run Code Online (Sandbox Code Playgroud)

Psy*_*nch 6

我通过反复试验发现我的特定问题可能是 Groovy 特定的。事实证明,测试代码和控制器代码没有问题。重申一下,为了测试表单提交,使用param方法 through 的perform方法MockMvcRequestBuilders。另一件要注意的事情是,如果未指定内容类型,这似乎不起作用。这是一个对我有用的示例测试代码:

MvcResult result = webApp.perform(post("/submit")
        .contentType(APPLICATION_FORM_URLENCODED) //from MediaType
        .param('title', 'test title')
        .param('description', 'test description'))
        .andReturn()
Run Code Online (Sandbox Code Playgroud)

如您所见,它与我最初发布的内容没有太大区别。控制器代码几乎相同,@ModelAttribute工作正常。

我的设置的问题是,因为我使用的是 Groovy,所以我认为 getter 和 setter 是在我的WriteUp类中自动生成的。这是WriteUp类最初的样子:

class WriteUp {
    private String title
    private String description
}
Run Code Online (Sandbox Code Playgroud)

我已经有一段时间没有在 Groovy 中编写代码了,而上一次我这样做时,可以假设上面的类隐式具有 getter 和 setter。然而,事实证明并非如此。为了解决我的具体问题,我将字段中的访问修饰符更新为default(包级别)

class WriteUp {
    String title
    String description
}
Run Code Online (Sandbox Code Playgroud)