Table of Contents

If you are not testing your code, you are just creating garbage. To avoid this we require a way to generate mocks for our classes to test our code.

Mockito is a simple, yet elegant way to inject mocks into your code without making a mess of it.

Read on to know how you can do this.

 

What is Mockito?

Mockito is a mocking framework designed for unit testing in Java. It allows you to write simple tests with a clean API. Tests written with this framework are easy to read and produce clean verification errors.

The key benefits of using Mockito are,

  • It has a friendly and massive StackOverflow community and thorough documentation, voted as the best mocking framework for Java.
  • Easy to use and understand as a first time mocker.
  • The @InjectMocks annotation makes it easier and cleaner to inject mocks into your code.

@InjectMocks

@InjectMocks is the Mockito Annotation. It allows you to mark a field on which an injection is to be performed.

Injection allows you to,

  • Enable shorthand mock and spy injections.
  • Minimize repetitive mock and spy injection.

Mockito will try to inject mocks only either by constructor injection, setter injection, or property injection, in order. If any of the following strategies fail, then Mockito won't report a failure.

From the Mockito Documentation,

    1. Constructor injection; the biggest constructor is chosen, then arguments are resolved with mocks declared in the test only. If the object is successfully created with the constructor, then Mockito won't try the other strategies. Mockito has decided not to corrupt an object if it has a parameterized constructor.
      1. Note: If arguments can not be found, then null is passed. If non-mockable types are wanted, then constructor injection won't happen. In these cases, you will have to satisfy dependencies yourself.
    2. Property setter injection; mocks will first be resolved by type (if a single type match injection will happen regardless of the name), then, if there are several properties of the same type, by the match of the property name and the mock name.
      1. Note 1: If you have properties with the same type (or same erasure), it's better to name all @Mock annotated fields with the matching properties, otherwise Mockito might get confused and injection won't happen.
      2. Note 2: If @InjectMocks instance wasn't initialized before and have a no-arg constructor, then it will be initialized with this constructor.
    3. Field injection; mocks will first be resolved by type (if a single type match injection will happen regardless of the name), then, if there is several property of the same type, by the match of the field name and the mock name.
      1. Note 1: If you have fields with the same type (or same erasure), it's better to name all @Mock annotated fields with the matching fields, otherwise Mockito might get confused and injection won't happen.
      2. Note 2: If @InjectMocks instance wasn't initialized before and have a no-arg constructor, then it will be initialized with this constructor.

Examples

public class ArticleManagerTest extends SampleBaseTestCase {

@Mock private ArticleCalculator calculator;
@Mock(name = "database") private ArticleDatabase dbMock; // note the mock name attribute
@Spy private UserProvider userProvider = new ConsumerUserProvider();

@InjectMocks private ArticleManager manager;

@Test public void shouldDoSomething() {
manager.initiateArticle();
verify(database).addListener(any(ArticleListener.class));
}
}

public class SampleBaseTestCase {

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

In the above example the field ArticleManager annotated with @InjectMocks could have a parameterized constructor only, a no-arg constructor only, or both.

All these constructors can be package protected, protected, or private. However, Mockito cannot instantiate inner classes, local classes, abstract classes, and, of course, interfaces. Beware of private nested static classes, too.

The same stands for setters or fields, they can be declared with private visibility. Mockito will see them through reflection. However, fields that are static or final will be ignored.

The constructor injection would look like this,

 public class ArticleManager {
ArticleManager(ArticleCalculator calculator, ArticleDatabase database) {
// parameterized constructor
}
}

Property setter injection would like this,

 public class ArticleManager {
// no-arg constructor
ArticleManager() { }

// setter
void setDatabase(ArticleDatabase database) { }

// setter
void setCalculator(ArticleCalculator calculator) { }
}

Field injection, like this,

 public class ArticleManager {
private ArticleDatabase database;
private ArticleCalculator calculator;
}

Always remember that the @InjectMocks annotation will only inject mocks/spies created using @Mock or @Spy annotations.

Finally…

Basically this annotation is an injection interface as it generates a new Mock from a designated object with specified properties. It then injects it as a “dependency” of sorts, and allows you to use it for further testing.

If you have any questions, contact me at rraya@nearsoft.com.

For more check out the first part of our Mockito series.

Learn More about Encora

We are the software development company fiercely committed and uniquely equipped to enable companies to do what they can’t do now.

Learn More

Global Delivery

READ MORE

Careers

READ MORE

Industries

READ MORE

Related Insights

Essential Guide to AWS Migration: Steps and Strategies

Discover the key steps and strategies for a successful AWS migration. Learn why AWS is a top cloud ...

Read More

Dynamic Pricing Reimagined: Leveraging AI to Balance Profitability and Customer Trust

To avoid the inevitable loss of customer trust and erosion of loyalty, retailers must exercise ...

Read More

Mastering Microsoft Microsoft Azure Migration: A Comprehensive Guide

Learn about Azure Migrate, the Azure migration process, tools, and services with our expert guide. ...

Read More
Previous Previous
Next

Accelerate Your Path
to Market Leadership 

Encora logo

+1 (480) 991 3635

letstalk@encora.com

Innovation Acceleration

Encora logo

+1 (480) 991 3635

letstalk@encora.com

Innovation Acceleration