f-lopes / spring-mvc-test-utils

Test library aimed to ease Spring MVC form validation tests. Easily post an entire form to a given url.
MIT License
19 stars 8 forks source link
spring-mvc spring-test

Gitpod ready-to-code

Spring MVC Test utils

Maven Central Build Status codecov

Codacy Badge Language grade: Java Dependabot Status

Test library aimed to ease Spring MVC form validation tests. Easily post an entire form to a given url.

See MockMvcRequestBuilderUtils

More details here: blog.florianlopes.io

How to use?

Add this dependency to your pom.xml file:

<dependency>
    <groupId>io.florianlopes</groupId>
    <artifactId>spring-mvc-test-utils</artifactId>
    <version>3.2.0</version>
    <scope>test</scope>
</dependency>

Note: since version 4.0.0, Java 11 is no longer supported, Java 17 is the minimum supported version.

This library is tested with Spring Framework 6.1.12 along with Java 17 and 21 ( see smoke-tests and build.yml workflow)


MockMvcRequestBuilderUtils.postForm("/url", formObject);

Example:

@Test
public void testSimpleFields() throws Exception {
    final MockHttpServletRequestBuilder mockHttpServletRequestBuilder = MockMvcRequestBuilderUtils.postForm("/test",
            new AddUserForm("John", "Doe", null, new Address(1, "Street", 5222, "New York")));
    final MockHttpServletRequest request = mockHttpServletRequestBuilder.buildRequest(this.servletContext);

    assertEquals("John", request.getParameter("firstName"));
    assertEquals("New York", request.getParameter("address.city"));
}

Usage with MockMvc:

final AddUserForm addUserForm = new AddUserForm("John", "Doe", null, new Address(1, "Street", 5222, "New York")));

mockMvc.perform(MockMvcRequestBuilderUtils.postForm("/users", addUserForm))
        .andExpect(MockMvcResultMatchers.model().hasNoErrors());

Using with() syntax (FormRequestPostProcessor):

final AddUserForm addUserForm = new AddUserForm("John", "Doe", null, new Address(1, "Street", 5222, "New York")));

// POST
mockMvc.perform(post("/users").with(MockMvcRequestBuilderUtils.form(addUserForm)))
        .andExpect(MockMvcResultMatchers.model().hasNoErrors());

// GET
mockMvc.perform(get("/users").with(MockMvcRequestBuilderUtils.form(addUserForm)))
        .andExpect(MockMvcResultMatchers.model().hasNoErrors());

// PUT
mockMvc.perform(put("/users").with(MockMvcRequestBuilderUtils.form(addUserForm)))
        .andExpect(MockMvcResultMatchers.model().hasNoErrors());

Register property editor(s)

This tool relies on default Spring's property editors ( see https://github.com/spring-projects/spring-framework/blob/main/spring-beans/src/main/java/org/springframework/beans/PropertyEditorRegistrySupport.java#L200).

If you want to override one of those registered by default, simple use the MockMvcRequestBuilderUtils.registerPropertyEditor(...) method:

MockMvcRequestBuilderUtils.registerPropertyEditor(LocalDate.class, new CustomLocalDatePropertyEditor("dd/MM/yyyy"));

final AddUserForm addUserForm = new AddUserForm("John", "Doe", LocalDate.now(), null);
final MockHttpServletRequestBuilder mockHttpServletRequestBuilder = MockMvcRequestBuilderUtils.postForm(POST_FORM_URL, addUserForm);

MockHttpServletRequest request = mockHttpServletRequestBuilder.buildRequest(this.servletContext);
assertEquals(LocalDate.now().format(DateTimeFormatter.ofPattern("dd/MM/yyyy")), request.getParameter("birthDate"));

Limitations and restrictions

This helper utility handles your form objects using the Java Reflection API. This implies some restrictions in the usage within your test cases:

Contributing

Feel free to contribute using this guide:

  1. Fork this project
  2. Clone your forked repository git clone git@github.com:{your-username}/spring-mvc-test-utils.git
  3. Add a new remote pointing to the original repository git remote add upstream git@github.com:flopes/spring-mvc-test-utils.git
  4. Create a new branch for your feature git branch -b my-feature
  5. Commit your changes (and squash them if necessary using git rebase -i or git add -p)
  6. Pull the latest changes from the original repository git checkout main && git pull --rebase upstream main
  7. Rebase main branch with your feature git checkout my-feature && git rebase main Solve any existing conflicts
  8. Push your changes and create a PR on GitHub git push -u origin my-feature Go to the original repository and create a new PR with comments.