Mockito Example with Best Practices

In this lesson, we will study Mockito, a full fledged framework in Java to create test doubles or mocks.

Introduction

Mockito is an Open Source Mocking framework in Java and provides easy ways to create test doubles, also referred to as mocks in further writing.

In Mockito, we mock behavior, not implementation by adding a dummy functionality to a mock interface that can be used in unit testing. This lesson will help you get started with Mockito API.

Mockito has an active group of developers with strong community support and is actively maintained, the last Mockito release is version 2.9.0.

Terminologies

Before moving to working examples with Mockito, we should know different types of Test objects that can be created and used in Mockito.

  • Dummy: This is an object that is used only for the code to compile and has no business logic associated with it like a parameter passed to a function.
  • Fake: This is an object that has an implementation but not ready for production, like H2 in-memory database.
  • Stub:  This is an object that has predefined answers to method executions made during the test.
  • Mock:  This is an object that has predefined answers to method executions made during the test and has recorded expectations of these executions.
  • Spy: This is an object that is similar to stubs, but they additionally record how they were executed.

Adding to classpath, using Maven

Best way to add Mockito dependency to your project is using Maven build system.

This dependency is simple enough and does not bring any additional or redundant libraries. See here for latest versions of the library.

Using Mockito API

We will get started with an example system under test (SUT) straight away, an easy one to start.

There are several methods in Mockito to create mock objects. Like:

  • Using @Mock annotation
  • Using static mock() method

When we make use of the @Mock annotation, we must trigger the creation of annotated objects. Let us demonstrate the usage of this annotation using an example:

When you use static mock method, you do not need to put @RunWith(MockitoJUnitRunner.class) or MockitoRule.
A lot was done in above example. Let us study step by step what’s happening.

  • We started with mock() with Iterator class. It tells Mockito to mock an Iterator class instance.
  • Next, we used Mockito static when a method to alter the results when a method of another class is called. This will make sure that particular data is returned when Iterator’s class when a method is called.
  • What follows is a sample code which calls the Iterator methods which invoke the when statement.
  • On the last line, we verify the results.

Also notice that at the beginning, we statically imported all methods in class Mockito. This allows us to use methods like verify and query.
Now, we will use the another example to be made using @Mock annotation.When you use @Mock annotation, you need to either use @RunWith(MockitoJUnitRunner.class) or MockitoRule.

With @RunWith(MockitoJUnitRunner.class)

In this test, we will return value from mock list based on parameters.
For example
If list.get(1) get called then it should return “Second element”

With MockitoRule

In this example, we will return same value from list irrespective of parameter.
For example
If you call list.get(1) or list.get(3), it will return you same value i.e. “Default Element”

Best practices with Mockito

The common understanding of unit testing is testing the smallest possible part of the software, specifically a method. In reality, we do not test methods; rather, we test a logical unit or the behavior of the system.

Readability

JUnit tests are written to test logical units. A test method name should portray the intention of the test so that a reader can understand what is being tested, such as the condition and the expectation or action.

Good test method names can be:

  • should_not_register_a_null_user()
  • should_throw_exception_when_a_null_user_is_registered()

Break Everything

An Extreme Programming concept is test everything that could possibly break. This means trying all different combinations of inputs to make sure we don’t miss any combination that can cause the class to generate an error.

Ignore Trivial Tests

Writing trivial JUnits (such that for getter and setter) is mostly a waste of time and money. We don’t have the luxury to write infinite tests as it can eat our development time, application build time, and reduce test maintainability. If we start writing tests for getter/setters, we may miss more useful test cases.

Staying away from debugging

A common practice when we find a bug is to start debugging an application—stop doing this. Rather, add more tests to break the code; this will enrich your test suite and improve the system documentation.

So anyway, before starting to debug, create an (integration) test that reproduces the issue and then debug it. This will narrow down the problem, create a unit test for the lowest possible unit, and keep both the tests for future reference.

Was this post helpful?

Leave a Reply

Your email address will not be published. Required fields are marked *