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
Partnering with Nicigas in their Energy Development Business
In Codeborne we have built energy information systems in Estonia, Sweden, Norway, Denmark, Luxembourg, Austria, and Japan. With Nicigas we combined our expertise and skillset to create something new on the Japanese market.
From wine tasting to digital innovation- the birth of the Wine Experience Club
We recently sat down with our client, Rait Maasikas, to go deeper into the story behind one of our more unusual recent projects- the Wine Experience Club.
Innovating the Austrian energy market with Spotty Smart Energy Partner
Spotty Smart Energy Partner GmbH, an Austrian energy provider, partnered with Codeborne to enhance their services and bring innovative energy solutions to the market