Partial mocks
Suppose we have this class:
public class Foo {
int getA() {
return 42;
}
int getB() {
return 1;
}
int getC() {
return getA() + getB();
}
} This is of course a simplified version - in the real version the getA() and getB() are quite complex and require other dependencies to be set, the getC() method has of course a more complex formula that depends on getA() and getB().Now our task is to write a test for method getC(). What is the best way to do that? I would like to ignore the actual implementation of getA() and getB() and only test if the results of these methods are used correctly. We ended up with this:
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
public class FooTest {
@Test public void getC() {
Foo foo = mock(Foo.class);
when(foo.getA()).thenReturn(12);
when(foo.getB()).thenReturn(11);
when(foo.getC()).thenCallRealMethod();
assertEquals(23, foo.getC());
}
} The code is quite short and relatively easy to read. But what slightly bothers me is that I am actually mocking the class that I am testing. While the thenCallRealMethod() clearly signals that I am actually calling the real method, it still feels slightly strange.Also the Mockito documentation recommends against using partial mocks unless you’re working on legacy code. This is not legacy code - I think the design is quite good - the logic of retrieving A and B is extracted to separate methods and getC() only deals with the calculation.An alternative would be to extend the Foo class inline and override getA() and getB() and return the required values. But this would yield a lot more lines of code and the readability would probably suffer.What do you think? Is this a good test? Can you suggest better alternatives?
Archived comments
Anton Arhipov 2010-06-11T22:01:53.603Z
the alternative you’ve listed is not better than using mockito, as extending Foo is actually the same as making a mock, but kind of an old-school way.no other suggestions though..
Our recent stories
B2B purchase financing with automated credit decisions
End-to-end B2B equipment-finance platform, from partner application intake to customer contracting. An automated solution for financing purchases for corporate customers, where a significant number of cases are auto-decided. Built and delivered by Codeborne.
Building for the future of insurance: our work on Swedbank P&C insurance claims
Our founders wrote the core of this internet bank in 2006-2007. Twenty years later, we're back inside it.
Flowers for a new generation - live in one month with AI as the pair programmer
How a long-time client's idea for reaching younger customers became our first project built systematically with AI from end to end - prototype, code, and content - while keeping every line reviewed and owned by us.