In object-oriented programming, mock objects are simulated objects that mimic the behaviour of real objects in controlled ways. A programmer typically creates a mock object to test the behaviour of some other object, in much the same way that a car designer uses a crash test dummy to simulate the dynamic behaviour of a human in vehicle impacts.
When should I mock?
A unit test should test a single code path through a single method. When the execution of a method passes outside of that method, into another object, and back again, you have a dependency.
When you test that code path with the actual dependency, you are not unit testing; you are integration testing. While that’s good and necessary, it isn’t unit testing.
Mockito Framework
Mockito is a mocking framework that tastes really good. It lets you write beautiful tests with a clean & simple API. Mockito doesn’t give you hangover because the tests are very readable and they produce clean verification errors.
Mockito is used to mock interfaces so that a dummy functionality can be added to a mock interface that can be used in unit testing.
More information can be found on below url:
https://site.mockito.org/
Enable Mockito Annotations
we need to enable the Mockito to use its annotation and functionality. There are 2 ways to enable the Mockito framework for our JUnit class.
@RunWith(MockitoJUnitRunner.class) public class TestClass { ... }
2. MockitoAnnotations.initMocks()
Alternatively, we can enable these annotations programmatically as well, by invoking MockitoAnnotations.initMocks() as in the following example:
@Before public void init() { MockitoAnnotations.initMocks(this); }
Service Layer –
package com.onlyfullstack.unittesting.service; import com.onlyfullstack.unittesting.bean.Customer; import com.onlyfullstack.unittesting.repository.CustomerRepository; import org.springframework.beans.factory.annotation.Autowired; public final class CustomerService { @Autowired public CustomerRepository repository; public boolean saveCustomer(Customer customer) { if (customer == null) { throw new IllegalArgumentException("Invalid Customer details passed."); } return repository.saveCusomer(customer); } public Customer getCustomer(Integer customerId) { if (customerId == null || customerId < 0) { throw new IllegalArgumentException("Invalid Customer details passed."); } return repository.getCustomer(customerId); } public void updateCustomer(Customer customer) { if (customer == null || customer.getId() < 0) { throw new IllegalArgumentException("Invalid Customer details passed."); } repository.updateCustomer(customer); } }
Repository Layer-
package com.onlyfullstack.unittesting.repository; import java.util.HashMap; import java.util.Map; import com.onlyfullstack.unittesting.bean.Customer; import org.springframework.stereotype.Component; @Component public class CustomerRepository { private static Map<Integer, Customer> customerMap = new HashMap<>(); { customerMap.put(1, new Customer(1, "ABC", "Pune")); customerMap.put(2, new Customer(2, "XYZ", "Pune")); customerMap.put(3, new Customer(3, "PQR", "Pune")); customerMap.put(4, new Customer(4, "MNO", "Pune")); } public boolean saveCusomer(Customer customer) { customerMap.put(customer.getId(), customer); return true; } public Customer getCustomer(Integer customerId) { return customerMap.get(customerId); } public void updateCustomer(Customer customer) { customerMap.put(customer.getId(), customer); } }
As you can see CustomerRepository is Autowired in CustomerService class. So we need to use @InjectMocks and we will see why and how it works.
Test Class-
package com.onlyfullstack.unittesting.service; import com.onlyfullstack.unittesting.bean.Customer; import com.onlyfullstack.unittesting.repository.CustomerRepository; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; import static org.hamcrest.CoreMatchers.is; import static org.junit.Assert.assertThat; import static org.mockito.Mockito.any; import static org.mockito.Mockito.eq; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; /** * This class contains usage of Mockito */ @RunWith(MockitoJUnitRunner.class) public class CustomerServiceTest { @Mock CustomerRepository repository; @InjectMocks CustomerService customerService; @Test public void saveCustomer_withValidCustomer() { Customer customer = new Customer(6, "QQQ", "Mumbai"); when(repository.saveCusomer(any())).thenReturn(true); Boolean save = customerService.saveCustomer(customer); assertThat(true, is(save)); verify(repository, times(1)).saveCusomer(eq(customer)); } }
@Mock will create a mock implementation for the CustomerRepository
@InjectMocks will inject the mocks marked with @Mock to this instance when it is created
Source Code
Download the source code of JUnit tutorial from below git repository :
unit-testing-and-integration-testing-with-spring-boot
Let’s go to our next tutorial where we will discuss below points :
1. when/then
2. when/thenThrow
3. when/thenAnswer
https://www.onlyfullstack.com/how-to-mock-methods-with-mockito/
Mockito Tutorial
https://www.onlyfullstack.com/mockito-tutorial/