Automated testing plays a vital role in the software industry. In this article, let us see how to do the testing using MockMvc for a Spring Boot project. To test the web layer, we need MockMvc and by using @AutoConfigureMockMvc, we can write tests that will get injected. SpringBootApplication is an excellent one that adds the following
- @Configuration
- @EnableAutoConfiguration
- @EnableWebMvc
- @ComponentScan
The application can ordinarily run as a Java application and hence development wise it is easier. Let’s see the concept via a sample project
Example Project
Project Structure:
Â
As it is a maven project, all dependencies are available underÂ
pom.xml
Dependencies like
- JDK 1.8
- Spring version from 2.2.5 onwards
- Maven 3.2+ and in the case of Gradle, it is Gradle 4+
We should add all the dependencies in pom.xml(in the case of the Maven project)
XML
<?xml version="1.0" encoding="UTF-8"?>Â Â Â Â Â Â Â Â Â xsi:schemaLocation="http://maven.apache.org/POM/4.0.0Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â http://maven.apache.org/xsd/maven-4.0.0.xsd">Â Â Â Â <modelVersion>4.0.0</modelVersion>Â
    <groupId>com.gfg.sample</groupId>    <artifactId>sampleboot-unit-testing-with-mock-mvc</artifactId>    <version>1.0-SNAPSHOT</version>Â
    <parent>        <groupId>org.springframework.boot</groupId>        <artifactId>spring-boot-starter-parent</artifactId>        <!-- Mandatory -->        <version>2.2.5.RELEASE</version>    </parent>Â
    <properties>        <java.version>1.8</java.version>    </properties>Â
    <dependencies>        <dependency>            <groupId>org.springframework.boot</groupId>            <artifactId>spring-boot-starter-web</artifactId>        </dependency>        <dependency>            <groupId>org.springframework.boot</groupId>            <artifactId>spring-boot-starter-test</artifactId>        </dependency>    </dependencies></project> |
We are using MockMvc to test the web layer. That is we should have a model. a controller, and a view. Let us see the controller file
WelcomeMvcController.java
Each and every method should have either Getmapping or Postmapping
Java
import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Controller;import org.springframework.ui.Model;import org.springframework.web.bind.annotation.GetMapping;Â
@Controllerpublic class WelcomeMvcController {    @Autowired    private WelcomeService welcomeService;         @GetMapping(value = "/")    public String greeting1(String name, Model model) {        model.addAttribute("welcome", welcomeService.greetingMessage1(name));        return "welcome-page";    }         @GetMapping(value = "/event")    public String greeting2(String name, Model model) {        model.addAttribute("welcomeToEvent", welcomeService.greetingMessage2(name));        return "event-page";    }} |
Required services are written in the service file
WelcomeService.java
Java
import org.springframework.stereotype.Service;Â
@Servicepublic class WelcomeService {Â Â Â Â public String greetingMessage1(String name) {Â Â Â Â Â Â Â Â return String.format("Welcome , %s to the world of programming!!!", name );Â Â Â Â }Â Â Â Â Â Â Â public String greetingMessage2(String attendee) {Â Â Â Â Â Â Â Â return String.format("Welldone , %s You are selected to the contest!!!", attendee );Â Â Â Â }} |
SpringBoot Application is run as an ordinary Java application only
WebAppMain.java
Java
import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;Â
@SpringBootApplicationpublic class WebAppMain {Â Â Â Â public static void main(String[] args) {Â Â Â Â Â Â Â Â SpringApplication.run(WebAppMain.class, args);Â Â Â Â }} |
Now let us start to write the test class that tests the web layer by using MockMvc
WelcomeWebAppTest.java
Java
import org.junit.Test;import org.junit.runner.RunWith;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;import org.springframework.boot.test.context.SpringBootTest;import org.springframework.test.context.junit4.SpringRunner;import org.springframework.test.web.servlet.MockMvc;import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;import org.springframework.test.web.servlet.result.MockMvcResultHandlers;import org.springframework.test.web.servlet.result.MockMvcResultMatchers;Â
@RunWith(SpringRunner.class)@SpringBootTest@AutoConfigureMockMvcpublic class WelcomeWebAppTest {    @Autowired    private MockMvc mockMvc;Â
    @Test    // We have to write out expectations and the      // expectations need to match with actuals      // When this is run, it imitates and accesses      // the web layer and get the output.    public void testWelcome() throws Exception {        this.mockMvc.perform(MockMvcRequestBuilders.get("/").param("name", "Geeks"))                .andExpect(MockMvcResultMatchers.status().isOk())                .andExpect(MockMvcResultMatchers.model().attribute("welcome",                        "Welcome , Geeks to the world of programming!!!"))                .andExpect(MockMvcResultMatchers.view().name("welcome-page"))                .andDo(MockMvcResultHandlers.print());    }Â
    @Test    public void testWelcomeToEvent() throws Exception {        this.mockMvc.perform(MockMvcRequestBuilders.get("/event").param("name", "Geeks"))                .andExpect(MockMvcResultMatchers.status().isOk())                .andExpect(MockMvcResultMatchers.model().attribute("welcomeToEvent",                        "Welldone , Geeks You are selected to the contest!!!"))                .andExpect(MockMvcResultMatchers.view().name("event-page"))                .andDo(MockMvcResultHandlers.print());    }Â
} |
Once the project is complete and does not contain any errors, we can run the test file as an ordinary JUNIT application
Â
Console Output:
Â
Â
Once we are getting response 200 means the service is available and the parameters are passed properly and it is producing a positive response. With that response, we are comparing the details by means of
Java
this.mockMvc.perform(MockMvcRequestBuilders.get("/").param("name", "Geeks"))                .andExpect(MockMvcResultMatchers.status().isOk()) // checking status                .andExpect(MockMvcResultMatchers.model().attribute("welcome",                        "Welcome , Geeks to the world of programming!!!")) // sent attribute and its value check                .andExpect(MockMvcResultMatchers.view().name("welcome-page")) // its view name check                .andDo(MockMvcResultHandlers.print()); |
Like this, we can test the web layer in the above-said ways
Conclusion
Automated testing helps to avoid tons of errors and error-free code and helps for good quality software. In the Spring Boot project, we can use MockMvc and can achieve the same.
