java parameters - Use Mockito to mock some methods but not others




object new (5)

The accepted answer is not correct according to the question.

The call to Stock stock = mock(Stock.class); calls org.mockito.Mockito.mock(Class<T>) which looks like this:

 public static <T> T mock(Class<T> classToMock) {
    return mock(classToMock, withSettings().defaultAnswer(RETURNS_DEFAULTS));
}

The docs of the value RETURNS_DEFAULTS tell:

/**
 * The default <code>Answer</code> of every mock <b>if</b> the mock was not stubbed.
 * Typically it just returns some empty value. 
 * <p>
 * {@link Answer} can be used to define the return values of unstubbed invocations. 
 * <p>
 * This implementation first tries the global configuration. 
 * If there is no global configuration then it uses {@link ReturnsEmptyValues} (returns zeros, empty collections, nulls, etc.)
 */

What you want is org.mockito.Mockito.CALLS_REAL_METHODS according to the docs:

/**
 * Optional <code>Answer</code> to be used with {@link Mockito#mock(Class, Answer)}
 * <p>
 * {@link Answer} can be used to define the return values of unstubbed invocations.
 * <p>
 * This implementation can be helpful when working with legacy code.
 * When this implementation is used, unstubbed methods will delegate to the real implementation.
 * This is a way to create a partial mock object that calls real methods by default.
 * <p>
 * As usual you are going to read <b>the partial mock warning</b>:
 * Object oriented programming is more less tackling complexity by dividing the complexity into separate, specific, SRPy objects.
 * How does partial mock fit into this paradigm? Well, it just doesn't... 
 * Partial mock usually means that the complexity has been moved to a different method on the same object.
 * In most cases, this is not the way you want to design your application.
 * <p>
 * However, there are rare cases when partial mocks come handy: 
 * dealing with code you cannot change easily (3rd party interfaces, interim refactoring of legacy code etc.)
 * However, I wouldn't use partial mocks for new, test-driven & well-designed code.
 * <p>
 * Example:
 * <pre class="code"><code class="java">
 * Foo mock = mock(Foo.class, CALLS_REAL_METHODS);
 *
 * // this calls the real implementation of Foo.getSomething()
 * value = mock.getSomething();
 *
 * when(mock.getSomething()).thenReturn(fakeValue);
 *
 * // now fakeValue is returned
 * value = mock.getSomething();
 * </code></pre>
 */

Thus your code should look like:

import org.junit.Test;
import static org.mockito.Mockito.*;
import static org.junit.Assert.*;

public class StockTest {

    public class Stock {
        private final double price;
        private final int quantity;

        Stock(double price, int quantity) {
            this.price = price;
            this.quantity = quantity;
        }

        public double getPrice() {
            return price;
        }

        public int getQuantity() {
            return quantity;
        }

        public double getValue() {
            return getPrice() * getQuantity();
        }
    }

    @Test
    public void getValueTest() {
        Stock stock = mock(Stock.class, withSettings().defaultAnswer(CALLS_REAL_METHODS));
        when(stock.getPrice()).thenReturn(100.00);
        when(stock.getQuantity()).thenReturn(200);
        double value = stock.getValue();

        assertEquals("Stock value not correct", 100.00 * 200, value, .00001);
    }
}

Is there any way, using Mockito, to mock some methods in a class, but not others?

For example, in this (admittedly contrived) Stock class I want to mock the getPrice() and getQuantity() return values (as shown in the test snippet below) but I want the getValue() to perform the multiplication as coded in the Stock class

public class Stock {
  private final double price;
  private final int quantity;

  Stock(double price, int quantity) {
    this.price = price;
    this.quantity = quantity;
  }

  public double getPrice() {
    return price;
  }

  public int getQuantity() {
    return quantity;
  }
  public double getValue() {
    return getPrice() * getQuantity();
  }

  @Test
  public void getValueTest() {
    Stock stock = mock(Stock.class);
    when(stock.getPrice()).thenReturn(100.00);
    when(stock.getQuantity()).thenReturn(200);
    double value = stock.getValue();
    // Unfortunately the following assert fails, because the mock Stock getValue() method does not perform the Stock.getValue() calculation code.
    assertEquals("Stock value not correct", 100.00*200, value, .00001);
}

Partial mocking using Mockito's spy method could be the solution to your problem, as already stated in the answers above. To some degree I agree that, for your concrete use case, it may be more appropriate to mock the DB lookup. From my experience this is not always possible - at least not without other workarounds - that I would consider as being very cumbersome or at least fragile. Note, that partial mocking does not work with ally versions of Mockito. You have use at least 1.8.0.

I would have just written a simple comment for the original question instead of posting this answer, but does not allow this.

Just one more thing: I really cannot understand that many times a question is being asked here gets comment with "Why you want to do this" without at least trying to understand the problem. Escpecially when it comes to then need for partial mocking there are really a lot of use cases that I could imagine where it would be useful. That's why the guys from Mockito provided that functionality. This feature should of course not be overused. But when we talk about test case setups that otherwise could not be established in a very complicated way, spying should be used.


Partial mocking of a class is also supported via Spy in mockito

List list = new LinkedList();
List spy = spy(list);

//optionally, you can stub out some methods:
when(spy.size()).thenReturn(100);

//using the spy calls real methods
spy.add("one");
spy.add("two");

//size() method was stubbed - 100 is printed
System.out.println(spy.size());

Check the 1.10.19 and 2.7.22 docs for detailed explanation.


According to docs :

Foo mock = mock(Foo.class, CALLS_REAL_METHODS);

// this calls the real implementation of Foo.getSomething()
value = mock.getSomething();

when(mock.getSomething()).thenReturn(fakeValue);

// now fakeValue is returned
value = mock.getSomething();

I think I've found a simpler answer to that question, to call the real method for just one method (even if it has a void return) you can do this:

Mockito.doCallRealMethod().when(<objectInstance>).<method>();
<objectInstance>.<method>();

Or, you could call the real method for all methods of that class, doing this:

<Object> <objectInstance> = mock(<Object>.class, Mockito.CALLS_REAL_METHODS);




java mocking mockito