Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mockito: method's return value depends on other method called

In my unit test I need to mock an interface which among different methods has nextItem() and isEmpty() methods:

public interface MyQueue {
    Item nextItem();
    boolean isEmpty();
    //other methods
    ...
}

My requirement for the mock is that isEmpty() initially should return false, but after nextItem() was called isEmpty() should return true. Thus I'm mocking a queue with one item.

  1. What is the simplest way to implement this kind of mock with mockito?
  2. Can I implement additional requirement: calling nextItem() second, third time and so on will result in a specific kind of exception?

P.S. I don't want to provide the full implementation of my interface for the test, because of other methods in it, resulting in hard-to-understand and verbose code.

like image 485
pavel_kazlou Avatar asked Sep 29 '12 21:09

pavel_kazlou


People also ask

Does Mockito spy call real method?

A mock does not call the real method, it is just proxy for actual implementations and used to track interactions with it. A spy is a partial mock, that calls the real methods unless the method is explicitly stubbed. Since Mockito does not mock final methods, so stubbing a final method for spying will not help.

Does mock object call real method?

In the given statement the real function kit. getResource() is called which leads to an NPE since function calls on resources are not mocked.

What is Mockito dependency?

Mockito is a popular mocking framework which can be used in conjunction with JUnit. Mockito allows us to create and configure mock objects. Using Mockito simplifies the development of tests for classes with external dependencies significantly.

How does Mockito when then return work?

Mockito when() method It enables stubbing methods. It should be used when we want to mock to return specific values when particular methods are called. In simple terms, "When the XYZ() method is called, then return ABC." It is mostly used when there is some condition to execute.


1 Answers

You can achieve that with thenAnswer(), a feature Mockito documentation sees as controversial:

Yet another controversial feature which was not included in Mockito originally. We recommend using simple stubbing with toReturn() or toThrow() only. Those two should be just enough to test/test-drive any clean & simple code.

Here's thenAnswer:

private boolean called = false;

when(mock.nextItem()).thenAnswer(new Answer() {
 Object answer(InvocationOnMock invocation) {   
     called = true;       
     return item;
 }
when(mock.isEmpty()).thenAnswer(new Answer() {
 Object answer(InvocationOnMock invocation) {          
     return called;
 }
});
like image 72
Assen Kolov Avatar answered Sep 20 '22 15:09

Assen Kolov