patternjavaCritical
Use Mockito to mock some methods but not others
Viewed 0 times
somemockitomethodsuseothersmockbutnot
Problem
Is there any way, using Mockito, to mock some methods in a class, but not others?
For example, in this (admittedly contrived)
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 classpublic 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);
}Solution
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:
In that case, each method implementation is mocked, unless specify
There is also a possibility the other way around with spy instead of mock:
In that case, all method implementation are the real one, except if you have defined a mocked behaviour with
There is one important pitfall when you use
Another possibility may be to use
This delegates unstubbed calls to real implementations.
However, with your example, I believe it will still fail, since the implementation of
Another possibility is to avoid mocks altogether:
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 implementationIn 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 implementationsIn 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 implementationsAnother 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);
}Code Snippets
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 implementationStock 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 implementationsStock 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@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);
}Context
Stack Overflow Q#14970516, score: 1037
Revisions (0)
No revisions yet.