Sunday 21 July 2019

Mockito: Mock static methods


In this post, I am going to explain how to mock static methods.

public class EmployeeService {

         public static List<String> getEmployeeFirstNames(List<Employee> employees){
                 throw new MethodNotImplementedException();
         }
}


As you see the above snippet, EmployeeService class has unimplemented method 'getEmployeeFirstNames'. If any methods that are using 'getEmployeeFirstNames' method in their implementation end up in 'MethodNotImplementedException'.

By using powermockito, we can mock and test static methods like below.

PowerMockito.mockStatic(EmployeeService.class);
Above statement mocks EmployeeService class.

PowerMockito.when(EmployeeService.getEmployeeFirstNames(employees)).thenReturn(employeeNames);
Above statement tells PowerMockito, return employeeNames, when getEmployeeFirstNames is called with employees.

Find the below working application.

MethodNotImplementedException.java
package com.sample.exceptions;

public class MethodNotImplementedException extends RuntimeException {
 private static final long serialVersionUID = 1L;

 public MethodNotImplementedException() {
  super();
 }

 public MethodNotImplementedException(String message) {
  super(message);
 }

}


Employee.java
package com.sample.model;

public class Employee {
 private int id;
 private String firstName;
 private String lastName;
 private double salary;
 private String country;

 public int getId() {
  return id;
 }

 public void setId(int 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;
 }

 public double getSalary() {
  return salary;
 }

 public void setSalary(double salary) {
  this.salary = salary;
 }

 public String getCountry() {
  return country;
 }

 public void setCountry(String country) {
  this.country = country;
 }

 public Employee(int id, String firstName, String lastName, double salary, String country) {
  this.id = id;
  this.firstName = firstName;
  this.lastName = lastName;
  this.salary = salary;
  this.country = country;
 }

 @Override
 public String toString() {
  StringBuilder builder = new StringBuilder();
  builder.append("Employee [id=").append(id).append(", firstName=").append(firstName).append(", lastName=")
    .append(lastName).append(", salary=").append(salary).append(", country=").append(country).append("]");
  return builder.toString();
 }

}


EmployeeService.java
package com.sample.service;

import java.util.List;

import com.sample.exceptions.MethodNotImplementedException;
import com.sample.model.Employee;

public class EmployeeService {

 public static List<String> getEmployeeFirstNames(List<Employee> employees) {
  throw new MethodNotImplementedException();
 }
}


EmployeeUtil.java
package com.sample.util;

import java.util.ArrayList;
import java.util.List;

import com.sample.model.Employee;

import com.sample.service.EmployeeService;

public class EmployeeUtil {

 /**
  * Return all employee names in upper case.
  * 
  * @param employees
  * @return
  */
 public List<String> getAllEmployeeFirstNamesInUpperCase(List<Employee> employees) {
  List<String> empNamesInLowerCase = EmployeeService.getEmployeeFirstNames(employees);
  List<String> result = new ArrayList<>(empNamesInLowerCase.size());

  for (String name : empNamesInLowerCase) {
   if (name == null) {
    continue;
   }

   result.add(name.toUpperCase());
  }

  return result;
 }

}


EmployeeUtilTest.java
package com.sample.test;

import static org.junit.Assert.assertEquals;

import java.util.ArrayList;
import java.util.List;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;

import com.sample.model.Employee;
import com.sample.service.EmployeeService;
import com.sample.util.EmployeeUtil;

@RunWith(PowerMockRunner.class)
@PrepareForTest({ EmployeeService.class })
public class EmployeeUtilTest {

 private List<Employee> employees;
 private List<String> employeeNames;

 @Before
 public void initList() {
  Employee emp1 = new Employee(1, "Hari krishna", "Gurram", 12345, "India");
  Employee emp2 = new Employee(2, "Kiran", "Kumnoor", 234556, "Germany");
  Employee emp3 = new Employee(3, "Soumen", "Mondle", 56789, "India");
  Employee emp4 = new Employee(4, "Sravya", "Guruju", 567890, "Japan");
  Employee emp5 = new Employee(5, "Rachit", "Kumar", 123645, "India");

  employees = new ArrayList<>();
  employeeNames = new ArrayList<>();

  employees.add(emp1);
  employees.add(emp2);
  employees.add(emp3);
  employees.add(emp4);
  employees.add(emp5);

  employeeNames.add("Hari krishna");
  employeeNames.add("Kiran");
  employeeNames.add("Soumen");
  employeeNames.add("Sravya");
  employeeNames.add("Rachit");
 }

 @Test
 public void getAllEmployeeFirstNamesInUpperCase_listOfEmployees_ListOfEmployeeNamesinUpperCase() {
  PowerMockito.mockStatic(EmployeeService.class);
  PowerMockito.when(EmployeeService.getEmployeeFirstNames(employees)).thenReturn(employeeNames);

  EmployeeUtil empUtil = new EmployeeUtil();

  List<String> employeeFirstNames = empUtil.getAllEmployeeFirstNamesInUpperCase(employees);

  assertEquals(employeeFirstNames.size(), 5);
  assertEquals(employeeFirstNames.get(0), "Hari krishna".toUpperCase());
  assertEquals(employeeFirstNames.get(1), "Kiran".toUpperCase());
  assertEquals(employeeFirstNames.get(2), "Soumen".toUpperCase());
  assertEquals(employeeFirstNames.get(3), "Sravya".toUpperCase());
  assertEquals(employeeFirstNames.get(4), "Rachit".toUpperCase());

 }
}

Important things to note here.
As you see the source code of EmployeeUtilTest.java class, it is annotated with two annotations ‘@RunWith’  and ‘@PrepareForTest’.

@RunWith(PowerMockRunner.class)
Above statement tells junit to run the test case using PowerMockRunner class.

@PrepareForTest({ EmployeeService.class })
Above statement tells PowerMock to prepare EmployeeService class for testing. By using this annotation we can mock final classes and test static, private methods.

PowerMockito.mockStatic(EmployeeService.class);
Above statement tells PowerMock that we would like to mock the static methods of EmployeeService class.

PowerMockito.when(EmployeeService.getEmployeeFirstNames(employees)).thenReturn(employeeNames);

Above statement tells powermock that return employeeNames, when getEmployeeNames is called with employees.


Previous                                                    Next                                                    Home

No comments:

Post a Comment