While
writing unit tests to the service layer, we need to mock the underlying data
access layer components. Since we are mocking data access layer components, we
no need to configure any data source.
@RunWith(MockitoJUnitRunner.class)
@SpringBootTest(webEnvironment = WebEnvironment.NONE)
public class EmployeeServiceUnitTest {
.....
.....
}
@RunWith(MockitoJUnitRunner.class)
Run this
test class with MockitoJUnitRunner.
@SpringBootTest(webEnvironment
= WebEnvironment.NONE)
Tell that
we are not testing any controllers.
Step 2: Create mock objects that are going to
be used by service component.
@Mock
private
EmployeeDaoImpl empDao;
Step 3: Mark service component with
@InjectMocks annotation on which injection should be performed.
@InjectMocks
private
EmployeeServiceImpl empService;
Step 4: Initializes objects annotated with
Mockito annotations for given testClass.
@Before
public
void setup() {
MockitoAnnotations.initMocks(this);
}
Step 5: Use mocked object while returning the
results.
when(empDao.save(any(Employee.class))).thenReturn(emp1);
Employee
persistedEmployee = empService.save(emp1);
Complete
test class looks like below.
@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());
}
}
Find the
below working application.
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-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;
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
Test
classes are given below.
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());
}
}
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 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());
}
}
{
@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());
}
}
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>
Total
project structure looks like below.
How to
run the test case?
Right
click on 'EmployeeServiceUnitTest.java' and Run As -> JUnit Test.
You can
download complete working application from this link.
No comments:
Post a Comment