Use Mockito to mock some methods but not others

To directly answer your question, yes, you can mock some methods without mocking others. This is called a partial mock. See the Mockito documentation on partial mocks for more information.

For your example, you can do something like the following, in your test:

Stock stock = mock(Stock.class);
when(stock.getPrice()).thenReturn(100.00);    // Mock implementation
when(stock.getQuantity()).thenReturn(200);    // Mock implementation
when(stock.getValue()).thenCallRealMethod();  // Real implementation

In that case, each method implementation is mocked, unless specify thenCallRealMethod() in the when(..) clause.

There is also a possibility the other way around with spy instead of mock:

Stock stock = spy(Stock.class);
when(stock.getPrice()).thenReturn(100.00);    // Mock implementation
when(stock.getQuantity()).thenReturn(200);    // Mock implementation
// All other method call will use the real implementations

In that case, all method implementation are the real one, except if you have defined a mocked behaviour with when(..).

There is one important pitfall when you use when(Object) with spy like in the previous example. The real method will be called (because stock.getPrice() is evaluated before when(..) at runtime). This can be a problem if your method contains logic that should not be called. You can write the previous example like this:

Stock stock = spy(Stock.class);
doReturn(100.00).when(stock).getPrice();    // Mock implementation
doReturn(200).when(stock).getQuantity();    // Mock implementation
// All other method call will use the real implementations

Another possibility may be to use org.mockito.Mockito.CALLS_REAL_METHODS, such as:

Stock MOCK_STOCK = Mockito.mock( Stock.class, CALLS_REAL_METHODS );

This delegates unstubbed calls to real implementations.


However, with your example, I believe it will still fail, since the implementation of getValue() relies on quantity and price, rather than getQuantity() and getPrice(), which is what you've mocked.

Another possibility is to avoid mocks altogether:

@Test
public void getValueTest() {
    Stock stock = new Stock(100.00, 200);
    double value = stock.getValue();
    assertEquals("Stock value not correct", 100.00*200, value, .00001);
}

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.