Step 1: Create a test class and annotate it
with @RunWith and @WebMvcTest annotations.
@RunWith(SpringJUnit4ClassRunner.class)
@WebMvcTest(EmployeeController.class)
public class EmployeeControllerUnitTest {
......
......
}
Step 2: Inject MockMvc object.
@Autowired
private
MockMvc mockMvc;
Step 3: Mock the service layer beans.
@MockBean
private
EmployeeService empService;
Step 4: Specify to junit that you want to
inject the mocked beans to contoller object.
@InjectMocks
private EmployeeController
employeeController;
Step 5: Initialie all mock objects before
starting the test case.
@Before
public
void setup() {
MockitoAnnotations.initMocks(this);
}
Step 6: Prepare mocked responses in service
layer.
Employee emp1 = new Employee();
emp1.setFirstName("Anil");
emp1.setLastName("Kumar");
emp1.setId(1);
when(empService.save(any(Employee.class))).thenReturn(emp1);
Step 7: Call controller APIs using mockMvc
object.
Below
snippet test the creation of new employee.
String payload = "{\"firstName\" : \"Anil\", \"lastName\" : \"Kumnar\", \"id\" : 1}";
MvcResult mvcResult = mockMvc.perform(post("/api/v1/employees").content(payload).contentType(MediaType.APPLICATION_JSON)).andReturn();
assertEquals(201, mvcResult.getResponse().getStatus());
Step 8:
You should specify
from where to scan the components using below statement.
@Configuration
@ComponentScan(basePackageClasses = { EmployeeController.class })
public static class TestConfiguration {
}
Total test
class looks like below.
@RunWith(SpringJUnit4ClassRunner.class)
@WebMvcTest(EmployeeController.class)
public class EmployeeControllerUnitTest {
@Autowired
private MockMvc mockMvc;
@MockBean
private EmployeeService empService;
@InjectMocks
private EmployeeController employeeController;
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
}
@Test
public void newEmployee() throws Exception {
Employee emp1 = new Employee();
emp1.setFirstName("Anil");
emp1.setLastName("Kumar");
emp1.setId(1);
when(empService.save(any(Employee.class))).thenReturn(emp1);
String payload = "{\"firstName\" : \"Anil\", \"lastName\" : \"Kumnar\", \"id\" : 1}";
MvcResult mvcResult = mockMvc
.perform(post("/api/v1/employees").content(payload).contentType(MediaType.APPLICATION_JSON))
.andReturn();
assertEquals(201, mvcResult.getResponse().getStatus());
System.out.println(mvcResult.getResponse().getContentAsString());
// assertEquals("{\"id\":1,\"firstName\":\"Anil\",\"lastName\":\"Kumar\"}",
// mvcResult.getResponse().getContentAsString());
}
@Configuration
@ComponentScan(basePackageClasses = { EmployeeController.class })
public static class TestConfiguration {
}
}
Find the
below working application.
Employee.java
package com.sample.app.model;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name = "employees")
public class Employee {
@Id
@GeneratedValue
@Column(name = "employee_name")
private Integer id;
@Column(name = "first_name")
private String firstName;
@Column(name = "last_name")
private String lastName;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
}
EmployeeDao.java
package com.sample.app.dao;
import java.util.List;
import com.sample.app.model.Employee;
public interface EmployeeDao {
public Employee save(Employee emp);
public List<Employee> all();
}
EmployeeDaoImpl.java
package com.sample.app.dao.impl;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
import com.sample.app.dao.EmployeeDao;
import com.sample.app.model.Employee;
@Repository
public class EmployeeDaoImpl implements EmployeeDao {
@PersistenceContext
private EntityManager entityManager;
@Override
@Transactional
public Employee save(Employee emp) {
entityManager.persist(emp);
entityManager.flush();
int id = emp.getId();
return entityManager.find(Employee.class, id);
}
@Override
public List<Employee> all() {
Query query = entityManager.createQuery("select e from Employee e", Employee.class);
return query.getResultList();
}
}
EmployeeService.java
package com.sample.app.service;
import java.util.List;
import com.sample.app.model.Employee;
public interface EmployeeService {
public Employee save(Employee emp);
public List<Employee> all();
}
EmployeeServiceImpl.java
package com.sample.app.service.impl;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.sample.app.dao.EmployeeDao;
import com.sample.app.model.Employee;
import com.sample.app.service.EmployeeService;
@Service
public class EmployeeServiceImpl implements EmployeeService {
@Autowired
EmployeeDao empDao;
@Override
public Employee save(Employee emp) {
return empDao.save(emp);
}
@Override
public List<Employee> all() {
return empDao.all();
}
}
HomeController.java
package com.sample.app.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class HomeController {
@RequestMapping("/")
public String homePage() {
return "Welcome to Spring boot Application Development";
}
}
EmployeeController.java
package com.sample.app.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import com.sample.app.model.Employee;
import com.sample.app.service.EmployeeService;
@RestController
@RequestMapping("api/v1/")
public class EmployeeController {
@Autowired
private EmployeeService empService;
@RequestMapping(value = "employees", method = RequestMethod.GET)
public ResponseEntity<List<Employee>> allEmployees() {
return ResponseEntity.ok(empService.all());
}
@RequestMapping(value = "employees", method = RequestMethod.POST)
public ResponseEntity<Employee> save(@RequestBody Employee emp) {
Employee persistedEmp = empService.save(emp);
return ResponseEntity.status(HttpStatus.CREATED).body(persistedEmp);
}
}
App.java
package com.sample.app;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
@SpringBootApplication
@EnableJpaAuditing
public class App {
public static void main(String args[]) {
SpringApplication.run(App.class, args);
}
}
application.properties
logging.level.root=WARN logging.level.org.hibernate=ERROR ## H2 specific properties spring.h2.console.enabled=true spring.h2.console.path=/h2 spring.datasource.url=jdbc:h2:file:~/db/myOrg.db;DB_CLOSE_ON_EXIT=FALSE;DB_CLOSE_DELAY=-1; spring.datasource.username=krishna spring.datasource.password=password123 spring.datasource.driverClassName=org.h2.Driver ## JPA specific properties # Creates the schema, destroying previous data. spring.jpa.hibernate.ddl-auto=create spring.jpa.database-platform=org.hibernate.dialect.H2Dialect spring.jpa.show-sql=true spring.jpa.properties.hibernate.format_sql=true ## Database connection pooling properties # Number of ms to wait before throwing an exception if no connection is available. spring.datasource.max-wait=10000 # Maximum number of active connections that can be allocated from this pool at the same time. spring.datasource.tomcat.max-active=10 spring.datasource.tomcat.max-idle=5 spring.datasource.tomcat.min-idle=3 spring.jpa.properties.hibernate.enable_lazy_load_no_trans=true
application-test.properties
logging.level.root=WARN logging.level.org.hibernate=ERROR spring.datasource.url=jdbc:h2:file:~/db/appTest.db;DB_CLOSE_ON_EXIT=FALSE;DB_CLOSE_DELAY=-1;
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
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>springTest</groupId>
<artifactId>springTest</artifactId>
<version>1</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.6.RELEASE</version>
</parent>
<name>springbootApp</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</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-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>
Test
classes are given below.
EmployeeServiceUnitTest.java
package com.sample.app.service;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.when;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.mockito.junit.MockitoJUnitRunner;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import com.sample.app.dao.impl.EmployeeDaoImpl;
import com.sample.app.model.Employee;
import com.sample.app.service.impl.EmployeeServiceImpl;
@RunWith(MockitoJUnitRunner.class)
@SpringBootTest(webEnvironment = WebEnvironment.NONE)
public class EmployeeServiceUnitTest {
@Mock
private EmployeeDaoImpl empDao;
@InjectMocks
private EmployeeServiceImpl empService;
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
}
@Test
public void newEmployee() {
Employee emp1 = new Employee();
emp1.setId(1);
emp1.setFirstName("Anil");
emp1.setLastName("Kumar");
when(empDao.save(any(Employee.class))).thenReturn(emp1);
Employee persistedEmployee = empService.save(emp1);
assertNotNull(persistedEmployee);
assertNotNull(persistedEmployee.getId());
assertEquals(emp1.getFirstName(), persistedEmployee.getFirstName());
assertEquals(emp1.getLastName(), persistedEmployee.getLastName());
}
}
EmployeeServiceIntegrationTest.java
package com.sample.app.service;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import com.sample.app.model.Employee;
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(webEnvironment=WebEnvironment.NONE)
@ActiveProfiles("test")
public class EmployeeServiceIntegrationTest {
@Autowired
EmployeeService empService;
@Test
public void newEmployee() {
Employee emp1 = new Employee();
emp1.setFirstName("Anil");
emp1.setLastName("Kumar");
Employee persistedEmployee = empService.save(emp1);
assertNotNull(persistedEmployee);
assertNotNull(persistedEmployee.getId());
assertEquals(emp1.getFirstName(), persistedEmployee.getFirstName());
assertEquals(emp1.getLastName(), persistedEmployee.getLastName());
}
}
EmployeeControllerIntegrationTest.java
package com.sample.app.controller;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.http.ResponseEntity;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import com.sample.app.model.Employee;
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
@ActiveProfiles("test")
public class EmployeeControllerIntegrationTest {
@Autowired
private EmployeeController empController;
@Test
public void newEmployee() {
Employee emp1 = new Employee();
emp1.setFirstName("Anil");
emp1.setLastName("Kumar");
ResponseEntity<Employee> response = empController.save(emp1);
Employee persistedEmployee = response.getBody();
assertNotNull(persistedEmployee);
assertNotNull(persistedEmployee.getId());
assertEquals(emp1.getFirstName(), persistedEmployee.getFirstName());
assertEquals(emp1.getLastName(), persistedEmployee.getLastName());
}
}
EmployeeControllerUnitTest.java
package com.sample.app.controller;
import static org.junit.Assert.assertEquals;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.when;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.MockitoAnnotations;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import com.sample.app.model.Employee;
import com.sample.app.service.EmployeeService;
@RunWith(SpringJUnit4ClassRunner.class)
@WebMvcTest(EmployeeController.class)
public class EmployeeControllerUnitTest {
@Autowired
private MockMvc mockMvc;
@MockBean
private EmployeeService empService;
@InjectMocks
private EmployeeController employeeController;
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
}
@Test
public void newEmployee() throws Exception {
Employee emp1 = new Employee();
emp1.setFirstName("Anil");
emp1.setLastName("Kumar");
emp1.setId(1);
when(empService.save(any(Employee.class))).thenReturn(emp1);
String payload = "{\"firstName\" : \"Anil\", \"lastName\" : \"Kumnar\", \"id\" : 1}";
MvcResult mvcResult = mockMvc
.perform(post("/api/v1/employees").content(payload).contentType(MediaType.APPLICATION_JSON))
.andReturn();
assertEquals(201, mvcResult.getResponse().getStatus());
System.out.println(mvcResult.getResponse().getContentAsString());
// assertEquals("{\"id\":1,\"firstName\":\"Anil\",\"lastName\":\"Kumar\"}",
// mvcResult.getResponse().getContentAsString());
}
@Configuration
@ComponentScan(basePackageClasses = { EmployeeController.class })
public static class TestConfiguration {
}
}
Total
project structure looks like below.
No comments:
Post a Comment