Skip to content

Latest commit

 

History

History
281 lines (209 loc) · 11 KB

README.org

File metadata and controls

281 lines (209 loc) · 11 KB

MOCKITO

What is Mockito?

Mockito is an open source testing framework for Java that allows the creation of test double objects in automated unit tests for the purpose of test-driven development or behavior-driven development.

What is Test Double?

Test Double is generic term used by Gerard Meszaros to mean any case where you replace a production object for testing purposes.

  • Dummy objects are passed around but never actually used. Usually they are just used to fill parameter lists.
  • Fake objects actually have working implementations, but usually take some shortcut which makes them not suitable for production (an InMemoryTestDatabase is a good example).
  • Stubs provide canned answers to calls made during the test, usually not responding at all to anything outside what’s programmed in for the test.
  • Spies are stubs that also record some information based on how they were called. One form of this might be an email service that records how many messages it was sent.
  • Mocks are pre-programmed with expectations which form a specification of the calls they are expected to receive. They can throw an exception if they receive a call they don’t expect and are checked during verification to ensure they got all the calls they were expecting

Why Mock?

Most of the time the code we write have dependencies. Often, delegates some work to other methods in other classes. If we are to use Unit testing, our test has to depend on those methods, but we want the tests to be independent of all other dependencies. We need a way to isolate a unit of code and test it alone.

Mockito Installation

There are different ways of adding Mockito into your project, below are some of the common ways.

  1. Download the jar file and at it to our project path.
  2. Add the dependency to the build automation tool that you are using in your project. E.g.
// Maven Dependency

<dependency>
	<groupId>org.mockito</groupId>
	<artifactId>mockito-all</artifactId>
	<version>1.9.5</version>
	<scope>test</scope>
</dependency>

// Gradle Dependency
testCompileorg.mockito:mockitocore:1.9.5// Ivy Dependency
<dependency org=”org.mockitoname=”mockito-corerev=”1.9.5conf=”test->default”/>

Using Mockito

After adding the dependencies in our project what next?

How to Inject Mocks?

Asuming we want to test a class in our application, we first create and inject the depencies using either annotations or Mockito’s static method mock()

Creating mock dependencies with mock() static method

The example below illustrate the use of Mockito without annotations to create and inject mocks.

private EtcBaseDao etcBaseDao;
private EtcBaseService etcBaseService;
    
@Before
public void setUp() {
  etcBaseDao = Mockito.mock(EtcBaseDao.class);
  etcBaseService = new EtcBaseService(etcBaseDao);
}

refer to com.etcbase.mockito.service.MockitoWithoutAnnotationTest.java in the source code for complete example.

Using @Mock and @InjectMocks annoations

The example below illustrate how to use Mockito’s annotation to create mock instances and inject them using the follwing annoations.

  • @Mock will create a new mock implementation for the given class.
  • @InjectMocks will inject the created mock to given class instance.
 // The method is called before the execution of every test in the test class.
@Mock // create a new mock implementation
private EtcBaseDao etcBaseDao;

@InjectMocks // inject the created mock instances in this class.
private EtcBaseService etcBaseService;

@Before
public void setUp() throws Exception {
  MockitoAnnotations.initMocks(this); // This line create an instance and insert all the mock dependencies.
}

refer to com.etcbase.mockito.service.MockitoWithAnnotationTest.java in the source code for complete example.

Tired of Using MockitoAnnotations.initMocks(this)

Some times litle thing can become boring, if you are tired of using the above way of satisfying dependencies you can add MockitoJUnitRunner or use MockitoJUnit4Runner from Spring in your test, it will take care of that. If you are using spring test, then you already have it. You can use it. Below is example using MockitoJUnit4Runner.

@Runwith(MockitoJUnit4Runner.class)
public class MockitoJUnit4RunnerTest {
 
  @Mock
  private EtcBaseDao etcBaseDao;

  @InjectMocks
  private EtcBaseService etcBaseService;
}

Mockito heavely uses static methods such as the once shown below.

METHODDESCRIPTION
thenThrow(Throwable toBeThrown)Throws given exception
thenThrow(Class<? extends Throwable> toBeThrown)
then(Answer answer)Uses user-created code toanswer
thenAnswer(Answer answer)
thenCallRealMethod()Calls real method when working with partial mock/spy
thenReturn(returnValue)Return the given value

Stubbing Method’s Return Value

The ability to return a test double as value when a method is called is called Stubbing. With Mockito you can specify how and what a method should return when it’s called e.g. using Mockito.when() with thenReturn()

The following arrange-act-assert pattern (similar to given-when-then, from Behavior Driven Development) a test should be splited into three parts (blocks) each with a specify responsibility.

//////////// Given then above behavior driven development Mockito also has BDDMockito class that introduces BDD semantics.

Mocking Methods with Mockito

After creating and injecting your mock, you should then tell Mockito how to behave when certain method are invoked.

Mockito.when(instanceName.methodName(methodArguments)).thenReturn(true);  // return true when the instance method is called.

Mockito.when(etcBaseService.save(etcBase)).thenReturn(etcBase);

refer to com.etcbase.mockito.service.MockitoWhenThenReturnTest.java in the source code for complete example.

We can also use matchers as shown below.

Mockito.when(etcBaseService.save(Mockito.any(EtcBase.class))).thenReturn(etcBase);

However, if there are more than one parameters in a method we cannot mix matchers and actual objects. We either have to use matcher for the parameters, or real objects and values.

Mockito.when(etcBaseService.getByIdAndDate(branchId, Mockito.any(Date.class))).thenReturn(etcBase); // this will throw exception.

refer to com.etcbase.mockito.service.MockitoMatcherTest.java in the source code for complete example.

When to use thenReturn, doReturn, Answer, doAnswer, thenAnswer, assertThat, and assertEquals?

  • You should use thenReturn() or doReturn() when you already know the return value at the time you mock the method call.
  • You should use Answer() or doAnswer() when you need to do additional things when a mocked method is invoked.
  • There is no much difference between must of Hamcrest matchers and junit asserts, only that hamcrest tends to given more information when there is an error with the test method.

Throwing Exception from a Method

We can use the JUnit expected to make sure that a method throw exception when it’s called.

@Test(expected = ExceptionName.class)

refer to com.etcbase.mockito.service.MockitoExpectedTest.java in source code for complete example.

Mocking Void Methods with Mockito

Even though void methods doesn’t return a value, behinde the scene it do return something depending on the programming language and implementation.

With Mockito we can use doAnswer() to mock a void method, doThrow() to throw an exception from a void method. The following example illustrate that.

Mockito.doAnswer(new Answer<Void>() {
			
   @Override
   public Void answer(InvocationOnMock invocationOnMock) throws Throwable {
     return null;
   }
}).when(etcBaseDao).delete(Mockito.any(Long.class));

refer to com.etcbase.mockito.service.MockitoVoidTest.java in the source code for complete example.

Using Verify with Mockito

Apart from asserting that the return values are valid, we can also verify that a given method is called on a given mock object during test execution, most especially when the method under test is a Void method.

There are two types of verify methods

  • One that takes the mock object only and
  • The second one that takes mock object and verification mode
Mockito.verify(theService).theMethod(...);

Mockito.verify(theService, Mockito.times(1)).theMethod(...);

refer to com.etcbase.mockito.service.MockitoWithVerifyTest.java in the source code for complete example.

Verification modes

  • Mockito.times(…)
  • Mockito.atLeast(…)
  • Mockito.atMost(…)
  • Mockito.calls(…)
  • Mockito.only(…)
  • Mockito.atLeastOnce()
  • Mockito.never()

Using ArgumentCaptor

The argument captor allows you to capture any argument that is passed into a mock method. Mockito.ArgumentCaptor

@Captor
private ArgumentCaptor<EtcBase> etcBaseArgumentCaptor;

refer to com.etcbase.mockito.service.MockitoArgumentCaptorTest.java in the source code for complete example.

Mockito Spy

It’s not alway that we want to mock everything, sometimes we do want to interact with the real service and verify that it was invoked, that is where Mockito spy is at your back.

When a dependency is annotated with @Spy Mockito will create a wrapper around the a real instance of that object so that it can be called.

@Spy // instead of using @Mock we use @Spy
private EtcBaseDao etcBaseDao;

Using MockitoJUnitRunner

The Mockito MockitoJUnitRunner give you automatic validation and automatic initMocks(). For example, in the case of automatic validation, Mockito might not instantly report an error when the Mockito.when() is used without then or thenReturn until when Mockito.verify() in reached.

@Test
public void successAutomaticValidation() {

 // Error is here but
 when(myMock.method1());
 
 // Do something here

 // Error is reported here
 verify(myMock).method2();
}

Also, as mention above. Instead of using MockitoAnnotations.initMocks(this); the runner gives you automatic initMocks()

ANY QUESTION?

If you have any question you can send it through my email address. [email protected]