Saturday, 3 August 2019

Spring boot: Testing the web application


This is continuation to my previous post, You can download previous complete working application from this link.

Step 1: Add ‘spring-boot-starter-test’ dependency to pom.xml.


I added below dependencies.

    <dependencies>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-data-jpa -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>

        <!-- https://mvnrepository.com/artifact/com.h2database/h2 -->
        <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-test -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>


    </dependencies>

Step 2:  Testing HomeController


As you see HomeController.java, it is defined like below.
@RestController
public class HomeController {

    @RequestMapping("/")
    public String homePage() {
        return "Welcome to Spring boot Application Development";
    }

}


As you see ‘homePage()’ method, it is simple and returning a string. We can easily test this method like below.
@Test
public void testHomePage() {
    HomeController homeController = new HomeController();
    String result = homeController.homePage();
    assertEquals(result, "Welcome to Spring boot Application Development");
}

Step 3: Testing EmployeeController

Let's test 'byId' method of EmployeeController class.
@RestController
@RequestMapping("api/v1/")
public class EmployeeController {

    @Autowired
    private EmployeeService empService;

    @RequestMapping(value = "employees/{id}", method = RequestMethod.GET)
    public ResponseEntity<Employee> byId(@PathVariable int id) {
        Optional<Employee> emp = empService.getEmployee(id);

        if (!emp.isPresent()) {
            return new ResponseEntity<>(HttpStatus.NOT_FOUND);
        }

        return ResponseEntity.ok(emp.get());

    }

    ......
    ......
}

As you see EmployeeController class, it is using EmployeeService instance to get the employees information. So to test EmployeeController class, we need to mock EmployeeService instance and inject it into EmployeeController instance before calling byId() method.


You can do that by using @InjectMocks, @Mock annotations.
public class EmployeeControllerTest {

    @InjectMocks
    private EmployeeController empController;

    @Mock
    private EmployeeService empService;

    @Before
    public void init() {
        /* This statement look for @InjectMocks and @Mock fields and init the mocks */
        MockitoAnnotations.initMocks(this);
    }

    ....
    ....
}

@InjectMocks
Mark a field on which injection should be performed.

@Mock
Mark a field as a mock.

MockitoAnnotations.initMocks(this);
Initializes objects annotated with Mockito annotations for given testClass.


EmployeeControllerTest.java
package com.sample.app.controller;

import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.when;
import static org.mockito.Mockito.verify;

import java.util.Optional;

import org.junit.Before;
import org.junit.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;

import com.sample.app.model.Employee;
import com.sample.app.service.EmployeeService;

public class EmployeeControllerTest {

    @InjectMocks
    private EmployeeController empController;

    @Mock
    private EmployeeService empService;

    @Before
    public void init() {
        /* This statement look for @InjectMocks and @Mock fields and init the mocks */
        MockitoAnnotations.initMocks(this);
    }

    @Test
    public void testById() {

        Employee mockedEmp = new Employee();
        mockedEmp.setId(1);

        Optional<Employee> empToReturn = Optional.of(mockedEmp);

        when(empService.getEmployee(1)).thenReturn(empToReturn);

        Employee employee = empController.byId(1).getBody();

        // Tests that getEmployee method called once.
        verify(empService).getEmployee(1);

        assertEquals(1, employee.getId());

    }
}

How to run the test case?

Right click on ‘EmployeeControllerTest.java’ -> Run As -> Junit Test.

Complete project structure is given below.


You can download complete working application from this link.


Note
You can even use hamcrest matchers to test the assertions. If you want to learn hamcrest, I would recommend you go through this post.


Previous                                                    Next                                                    Home

No comments:

Post a Comment