Mockito Tutorial: Mockito Framework for Mocking in Unit Testing

A Complete Guide to Mockito Framework: Hands-on Mockito Tutorials

Unit testing is a simple yet effective technique to gain a good level of confidence in the code that is to be shipped.

Moreover, it avoids regression issues with every piece of code that gets checked in.

With micro-services kind of architecture (and even for simple structure involving basic database calls), straightforward unit testing does not suffice. What we need is to mock the dependencies and test the actual logic of the method under test.

Mockito tutorial guide

List of ALL Mockito Tutorials in this Series:

Tutorial #1: Mockito Framework for Mocking in Unit Testing (This Tutorial)
Tutorial #2: Creating Mocks and Spies in Mockito
Tutorial #3: Different Types of Matchers Provided by Mockito
Tutorial #4: Mocking Private, Static and Void Methods Using Mockito
Tutorial #5: Top 12 Mockito Interview Questions

**********************************************************************

Overview of Tutorials in this Mockito Series

Tutorial #What You Will Learn
Tutorial #1:Mockito Framework for Mocking in Unit Testing

Learn mocking with Mockito - A comprehensive Mockito Tutorial for beginners with code examples. Learn Mocking Framework for Mocking in Unit Testing.
Tutorial #2:Creating Mocks and Spies in Mockito

Mocks and Spies are types of test doubles, which are helpful in writing unit tests. Both are explained in this Mockito Spy tutorial with code examples.
Tutorial #3:Different Types of Matchers Provided by Mockito

Learn how to use different types of matchers provided by Mockito. Matchers are like wildcards where instead of a specific input/output, you specify a range of input. Argument and Verification are the two types of Matchers in Mockito which are explained in detail here.
Tutorial #4:Mocking Private, Static and Void Methods Using Mockito

Learn Mocking Private, Static and Void methods in Mockito with Examples. Learn Mocking private and static methods by unit testing framework PowerMockito.
Tutorial #5:Top 12 Mockito Interview Questions

Mockito Interview Questions and answers with sample code examples. This will help you to crack any Mockito Mocking Framework interview successfully.

Let's start with the first tutorial in this series!!

Mocking in Unit testing

Mocks/Stubs is a term that people commonly hear while creating unit tests in particular.

So, what essentially is Mocking? In simple terms, it's nothing but providing a controlled instance or implementation of dependency that the code under test depends on in order to test its core logic.

The reason I mentioned it as a controlled instance is that the behavior of the dependency can be programmed or controlled as desired for the method or system under test.

To explain it diagrammatically, let’s take an example of any Business or Ecommerce Application. Almost every such type of application primarily has 3 layers i.e. User Interface, Business Layer & Data Access layer (which talks to the underlying data store)

Example: UnitTesting Dependencies

Referring to the above diagram, Business Layer has 3 dependencies namely i.e. Data Access Layer and 2 other services which are Service 1 and Service 2.

Look at it this way – An app like google maps can have dependencies on an

  1. Actual data stores like MySQL or any other no SQL database which stores Map data.
  2. An external service like CoordinateService which provides latitudes and longitudes of a location.
  3. An external service like traffic service which provides real-time traffic information for a given Coordinate pair.

So, if someone is trying to validate the core business logic using unit test, until and unless they have working implementations of these dependencies, the tests could not be run.

Mocks come to rescue in these situations, where no matter your dependency is up and running or not, you are always guaranteed to run your business logic with a programmed response for the dependency that’s being getting called from the code under test.

Types/Categories of Test Doubles

Mock is essentially a type of “Test Double” – it’s a tech jargon. “Test Double” essentially means an object which is replaced by equivalent real object instance or dependency.

There are different types of Test doubles as mentioned below:

#1) Fakes:

A fake is a working implementation similar to a real dependency, except the fact that it is local to the system under test.

Example: Instead of hitting a real production DB, the test uses a simple collection/in-memory to store data.

Type of Test Doubles - Fakes

#2) Stubs:

Stubs are pre-configured responses when a dependency is called from the system under test.

Type of Test Doubles- Stubs

#3) Spies: 

As the name suggests, its actually the real function (dependency) call with some watching mechanism. Post the call, it can be verified whether the call was actually triggered or not along with the parameters.

Type of Test Doubles- Spies

#4) Mocks: 

Mocks are special instances of objects, on which Stubbed/pre-configured responses can be specified. The fact that the mock got called can be verified as an assert in the test.

For Example:

There is a report generator function which sends an email to a specified address during execution.

As we don’t want to send actual email, again and again, during testing, the EmailService is mocked (and the email method which sends the email is configured to do nothing when it’s called). At the end of the test, we can just verify that the email sending method of the email service got called through the mocked object.

Different Mocking Frameworks

Almost all the languages provide different kinds of mocking frameworks. We will be writing a sample code using Mockito which is an open source Mocking framework for Java.

Anatomy of a simple unit test with mocked dependency. Suppose, we are trying to unit test an application which calculates total marks for a student in all the subjects and writes it to DB.

public void calculateSumAndStore(String studentId, int[] scores)
 {
    int total = 0;
    for (int score: scores) {
        total = total + score;
    } // write total to DB
    databaseImpl.updateScores(studentId, total);
  }  

Now if we want to write a unit test for the method – calculateSumAndStore , then we might not be having a real implementation of a database to store the total. In that case, we won’t ever be able to unit test this function.

But with mocks in place, we can simply pass a Mock for database service and validate the rest of the logic

Sample test as shown below:

@Test
public void calculateSumAndStore_withValidInput_shouldCalculateAndUpdateResultInDb()
 {
   // Arrange
    studentScores = new StudentScoreUpdates(mockDatabase);
    int[] scores = {  60, 70, 90  };
    Mockito.doNothing().when(mockDatabase).updateScores("student1", 220); 

    // Act
    studentScores.calculateSumAndStore("student1", scores); 

    // Assert
    Mockito.verify(mockDatabase, Mockito.times(1)).updateScores("student1", 220);
}

We seen in the above test, we have provided a mockDatabase object to the parent class (for the method under test) and we’ve set up a stub response for the mockedDatabase object – Line#6 above (Mockito.doNothing().when(mockDatabase).updateScores(“student1”, 220);)

The important points to note from the above are:


#1) The mocked object need to setup stubbed responses for all the methods that will be called during the function execution.

#2) The parameters specified during stub creation can be specific or generic.

Example in the above case – we have specified the parameters for the updateScores method as “student1” and 220 because we know that these are the exact inputs with which our method is going to be called.

#3) During verification, we are validating the following:

  • mockDatabase.updateScores method was called.
  • Arguments were “student1” & 220 respectively.
  • The updateScores method was called 1 time.

Now let’s try changing this test code a bit and see what happens:

I will change the argument in the mock setup from “student1” to anyString (Mockito provides a standard matcher named anyString()) & 220 to anyInteger (Mockito provides a standard matcher named anyInt() and it matches any integer value)

@Test
public void calculateSumAndStore_withValidInput_shouldCalculateAndUpdateResultInDb()
 {
   // Arrange
    studentScores = new StudentScoreUpdates(mockDatabase);
    int[] scores = {  60, 70, 90  };
    Mockito.doNothing().when(mockDatabase).updateScores(anyString(), anyInt()); 

    // Act
    studentScores.calculateSumAndStore("student1", scores); 

    // Assert
    Mockito.verify(mockDatabase, Mockito.times(1)).updateScores("student1", 220);
}

Try running the test again and The test should still be green.

[Now let’s try changing the verification/asserts and change any one of the arguments.

Let's change 220 to 230. Now the expectation is that the test should fail as this is not the expected argument that the databaseUpdate must have been called with.

@Test
public void calculateSumAndStore_withValidInput_shouldCalculateAndUpdateResultInDb()
 {
   // Arrange
    studentScores = new StudentScoreUpdates(mockDatabase);
    int[] scores = {  60, 70, 90  };
    Mockito.doNothing().when(mockDatabase).updateScores(anyString(), anyInt()); 

    // Act
    studentScores.calculateSumAndStore("student1", scores); 

    // Assert
    Mockito.verify(mockDatabase, Mockito.times(1)).updateScores("student1", 230);
}

After running the test, refer to the error logs as shown below (it clearly mentions that the actual arguments did not match the expected ones).

Argument(s) are different! Wanted:
mockDatabase.updateScores(“student1”, 230);
-> at com.mocking.sampleMocks.StudentScoreUpdatesUnitTests.calculateSumAndStore_withValidInput_shouldCalculateAndUpdateResultInDb(StudentScoreUpdatesUnitTests.java:37)

Actual invocation has different arguments:
mockDatabase.updateScores(“student1”, 220);

Source code

Interface – IDatabase.java

public interface IDatabase { 

public void updateScores(String studentId, int total);
}

Class Under Test – StudentScoreUpdates.java

public class StudentScoreUpdates {
public IDatabase databaseImpl; 

public StudentScoreUpdates(IDatabase databaseImpl)
{
this.databaseImpl = databaseImpl;
} 

public void calculateSumAndStore(String studentId, int[] scores)
{
int total = 0;
for(int score : scores)
{
total = total + score;
}
// write total to DB
databaseImpl.updateScores(studentId, total);
}
}

Unit Tests Class – StudentScoreUpdatesUnitTests.java

public class StudentScoreUpdatesUnitTests { 

@Mock
public IDatabase mockDatabase; 

public StudentScoreUpdates studentScores; 

@BeforeEach
public void beforeEach()
{
MockitoAnnotations.initMocks(this);
} 

@Test
public void calculateSumAndStore_withValidInput_shouldCalculateAndUpdateResultInDb()
{
// Arrange
studentScores = new StudentScoreUpdates(mockDatabase);
int[] scores = {60,70,90};
Mockito.doNothing().when(mockDatabase).updateScores(anyString(), anyInt()); 

// Act
studentScores.calculateSumAndStore("student1", scores); 

// Assert
Mockito.verify(mockDatabase, Mockito.times(1)).updateScores("student1", 230);
} 

}

Conclusion

What we saw so far is a very basic and straightforward example of Mock setup using Java’s Mockito framework.

For almost 60-70% of unit tests involving mocks the tests should have a similar structure. Mockito does provide a lot of advanced configuration/support for extensive mocking needs, injecting mock instances using dependency injection, provides Spies to actually spy on a real method call and verify the calls.

Our upcoming tutorial will explain more about the Concept of Mocks and Spies in Mockito.

NEXT Tutorial