Testing Spring Boot with TestNG - Chapter 5: Testing Spring MVC

Keywords: Java Spring github Junit

Testing Spring Boot with TestNG

I prefer to use TestNG for unit and integration testing, so the examples in this paper are based on TestNG.
And Spring & Spring Bot's official examples of Testing are mostly based on JUnit, so this article can also provide some useful help to TestNG enthusiasts.

Github address

Chapter List

  1. Chapter 0: Basic Concepts
  2. Chapter 1: Basic usage
  3. Chapter 2: Annotation Test Tool
  4. Chapter 3: Using Mockito
  5. Chapter 4: Testing Relational Databases
  6. Chapter 5: Testing Spring MVC
  7. Chapter 6: Test @Configuration TODO
  8. Chapter 7: Test @AutoConfiguration TODO
  9. Appendix I Spring Mock Objects
  10. Appendix II Spring Test Utils

Chapter 5: Testing Spring MVC

Spring Testing Framework Provided Spring MVC Test Framework It's easy to test Controller. Spring Boot also provides Auto-configured Spring MVC tests It further simplifies the configuration work needed for testing.

This chapter will illustrate how to test Spring MVC without Spring Boot and with Spring Boot, respectively.

Example 1: Spring

The key to testing Spring MVC is to use MockMvc objects, which allow us to test Controller behavior without starting the Servlet container.

source codeSpringMvc_1_Test.java:

@EnableWebMvc
@WebAppConfiguration
@ContextConfiguration(classes = { FooController.class, FooImpl.class })
public class SpringMvc_1_Test extends AbstractTestNGSpringContextTests {

  @Autowired
  private WebApplicationContext wac;

  private MockMvc mvc;

  @BeforeMethod
  public void prepareMockMvc() {
    this.mvc = webAppContextSetup(wac).build();
  }

  @Test
  public void testController() throws Exception {

    this.mvc.perform(get("/foo/check-code-dup").param("code", "123"))
        .andDo(print())
        .andExpect(status().isOk())
        .andExpect(content().string("true"));

  }

}

In this code, there are three main steps:

  1. Mark the test class as @WebAppConfiguration
  2. Building MockMvc through webAppContextSetup(wac).build()
  3. Using MockMvc to Judge the Result

Example 2: Spring + Mock

In Example 1, FooController uses an entity FooImpl's Bean. In fact, we can also provide a Foo's mock bean for testing, so that we can control the testing process more. If you don't know Mock yet, seeChapter 3: Using Mockito.

source codeSpringMvc_2_Test.java:

@EnableWebMvc
@WebAppConfiguration
@ContextConfiguration(classes = { FooController.class })
@TestExecutionListeners(listeners = MockitoTestExecutionListener.class)
public class SpringMvc_2_Test extends AbstractTestNGSpringContextTests {

  @Autowired
  private WebApplicationContext wac;

  @MockBean
  private Foo foo;

  private MockMvc mvc;

  @BeforeMethod
  public void prepareMockMvc() {
    this.mvc = webAppContextSetup(wac).build();
  }

  @Test
  public void testController() throws Exception {

    when(foo.checkCodeDuplicate(anyString())).thenReturn(true);

    this.mvc.perform(get("/foo/check-code-dup").param("code", "123"))
        .andDo(print())
        .andExpect(status().isOk())
        .andExpect(content().string("true"));

  }

}

Example 3: Spring Boot

Spring Boot provides @WebMvcTest to further simplify the testing of Spring MVC. We provide the Spring Boot version of the corresponding example 1.

source codeBootMvc_1_Test.java:

@WebMvcTest
@ContextConfiguration(classes = { FooController.class, FooImpl.class })
public class BootMvc_1_Test extends AbstractTestNGSpringContextTests {

  @Autowired
  private MockMvc mvc;

  @Test
  public void testController() throws Exception {

    this.mvc.perform(get("/foo/check-code-dup").param("code", "123"))
        .andDo(print())
        .andExpect(status().isOk())
        .andExpect(content().string("true"));

  }

}

Here, we don't need to build MockMvc ourselves, just use @Autowired injection. Is it convenient?

Example 4: Spring Boot + Mock

This is the Spring Book version corresponding to Example 2, source codeBootMvc_2_Test.java:

@WebMvcTest
@ContextConfiguration(classes = { FooController.class })
@TestExecutionListeners(listeners = MockitoTestExecutionListener.class)
public class BootMvc_2_Test extends AbstractTestNGSpringContextTests {

  @Autowired
  private MockMvc mvc;

  @MockBean
  private Foo foo;

  @Test
  public void testController() throws Exception {

    when(foo.checkCodeDuplicate(anyString())).thenReturn(true);

    this.mvc.perform(get("/foo/check-code-dup").param("code", "123"))
        .andDo(print())
        .andExpect(status().isOk())
        .andExpect(content().string("true"));

  }

}

Reference Documents

Posted by cbesh2 on Sun, 06 Jan 2019 02:36:09 -0800