Test controller with Mock MVC in Spring Boot

Test the controller created by Spring MVC from JUnit using MockMVC.

What is MockMVC

You can reproduce the behavior of Spring MVC without deploying to the application server. MockMVC makes it easy to create controller tests. To use MockMVC with Spring Boot, add the following description to build.gradle.

build.gradle


testCompile('org.springframework.boot:spring-boot-starter-test')

When you create a project with SPRING INITIALIZR https://start.spring.io/, it is described in build.gradle by default.

environment

In order to try MockMVC this time, I created a project with SPRING INITIALIZR https://start.spring.io/. The project settings are as follows. Since Spring MVC and Thymeleaf are used, please select as you like except to add Web and Thymeleaf to dependency.

--Spring Boot version: 2.0M7 --Build tool: Gradle --Language: Kotlin

In this environment, create a page with two text boxes and a registration button for entering the user name and email address as shown below.

スクリーンショット 2017-12-28 17.43.49.png

Test with MockMVC that the input page is displayed when accessing the root URL from the browser. Since the purpose is to try MockMVC, processing other than page display is omitted.

Creating a controller

Create a controller that displays index.html for GET requests to the root URL.

UserController.kt


@Controller
class UserController {

    @RequestMapping(value = "/", method = [(RequestMethod.GET)])
    fun index(model: Model): String {
        model.addAttribute("userForm", UserForm())
        return "index"
    }
}    

Creating a form class

Create a class for the input form. Kotlin allows you to use the data class, so it's simple to write.

UserForm.kt


data class UserForm(val name: String = "", val mail: String = "")

Create view

I added the following to build.gradle to use BootStrap.

build.gradle


compile group: 'org.webjars', name: 'bootstrap', version: '3.3.7-1'

In Thymeleaf, create a page with a textbox and a button as shown below.

index.html


<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <link rel="stylesheet" th:href="@{/webjars/bootstrap/3.3.7-1/css/bootstrap.min.css}" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>user registration</title>
</head>
<body>
    <div class="container">
        <h1>user registration</h1>
        <form id="userForm" method="post" th:action="@{/user}" th:object="${userForm}" action="/user">
            <div class="form-group">
                <label for="name">Name</label>
                <input class="form-control" id="name" type="text" th:feild="*{name}" name="name" placeholder="Name"/>
            </div>
            <div class="form-group">
                <label for="mail">Mail</label>
                <input class="form-control" id="mail" type="text" th:feild="*{mail}" name="mail" placeholder="Mail"/>
            </div>
            <button type="submit" class="btn btn-primary">Registration</button>
        </form>
    </div>
</body>
</html>

Creating a test

Send a GET request to the root URL and test the following in the response obtained. --Index.html is displayed as a view --Status code is 200 --The values of the name attribute, placeholder attribute, and value attribute of the text box are correct.

Create a test class as follows.

UserControllerTest.kt


@RunWith(SpringRunner::class) // ①
@WebMvcTest // ②
class UserControllerTest {

    @Autowired
    private lateinit var mockMvc: MockMvc  // ③

    @Test
    fun test1() {
        this.mockMvc.perform(get("/"))               // ④ 
                .andExpect(status().isOk)            // ⑤
                .andExpect(view().name("index"))     // ⑥
                .andExpect(xpath("/html/head/title").string("Title"))    // ⑦
                .andExpect(xpath("""//*[@id="name"]/@name""").string("name"))
                .andExpect(xpath("""//*[@id="name"]/@placeholder""").string("Name"))
                .andExpect(xpath("""//*[@id="name"]/@value""").string(""))
                .andExpect(xpath("""//*[@id="mail"]/@name""").string("mail"))
                .andExpect(xpath("""//*[@id="mail"]/@placeholder""").string("Mail"))
                .andExpect(xpath("""//*[@id="mail"]/@value""").string(""))
    }

}

―― ① Used to test Spring with JUnit. --② Use @WebMvcTest to test views and controllers using MockMVC. --③ DI the instance of MockMvc --④ Send a GET request ――⑤ Check the HTTP status. --⑥ Check that index.html is displayed as a view. --⑦ Check that each attribute of the text box is correct. You can get the attribute value of the textbox by XPath

Run the test

You can run it as a JUnit test from the IDE. When specifying the test class from gradlew, specify as follows.

./gradlew test --tests "package.ControllerTest"

Recommended Posts

Test controller with Mock MVC in Spring Boot
Write test code in Spring Boot
Test Spring framework controller with Junit
Perform transaction confirmation test with Spring Boot
Form class validation test with Spring Boot
Sample code to unit test a Spring Boot controller with MockMvc
SameSite cookie in Spring Boot (Spring Web MVC + Tomcat)
Asynchronous processing with regular execution in Spring Boot
Download with Spring Boot
Include external jar in package with Spring boot2 + Maven3
Spring Security usage memo: Cooperation with Spring MVC and Boot
[JUnit 5 compatible] Write a test using JUnit 5 with Spring boot 2.2, 2.3
SSO with GitHub OAuth in Spring Boot 1.5.x environment
[JUnit 5] Write a validation test with Spring Boot! [Parameterization test]
Test field-injected class in Spring boot test without using Spring container
Until you start development with Spring Boot in eclipse 1
Until you start development with Spring Boot in eclipse 2
I wrote a test with Spring Boot + JUnit 5 now
Database environment construction with Docker in Spring boot (IntellJ)
Set context-param in Spring Boot
Generate barcode with Spring Boot
Hello World with Spring Boot
Java Config with Spring MVC
Implement GraphQL with Spring Boot
[Spring] Controller exception output test
Get started with Spring boot
Hello World with Spring Boot!
Spring Boot 2 multi-project in Gradle
Run LIFF with Spring Boot
SNS login with Spring Boot
File upload with Spring Boot
Spring Boot starting with copy
Spring Boot starting with Docker
Hello World with Spring Boot
Set cookies with Spring Boot
Use Spring JDBC with Spring Boot
Major changes in Spring Boot 1.5
Add module with Spring Boot
Getting Started with Spring Boot
NoHttpResponseException in Spring Boot + WireMock
Create microservices with Spring Boot
Send email with spring boot
Spring boot controller method memo
MOCK constructors of other classes with Spring MVC + PowerMock + Junit
Use thymeleaf3 with parent without specifying spring-boot-starter-parent in Spring Boot
Use Basic Authentication with Spring Boot
Spring Boot application development in Eclipse
gRPC on Spring Boot with grpc-spring-boot-starter
Create an app with Spring Boot 2
Hot deploy with Spring Boot development
Database linkage with doma2 (Spring boot)
Spring Boot programming with VS Code
Until "Hello World" with Spring Boot
Inquiry application creation with Spring Boot
Get validation results with Spring Boot
Implement file download with Spring MVC
(Intellij) Hello World with Spring Boot
Create an app with Spring Boot
Implement REST API in Spring Boot
What is @Autowired in Spring boot?
Google Cloud Platform with Spring Boot 2.0.0