I'd like to test an abstract class. Sure, I can manually write a mock that inherits from the class.
Can I do this using a mocking framework (I'm using Mockito) instead of hand-crafting my mock? How?
I'd like to test an abstract class. Sure, I can manually write a mock that inherits from the class.
Can I do this using a mocking framework (I'm using Mockito) instead of hand-crafting my mock? How?
The following suggestion lets you test abstract classes without creating a "real" subclass - the Mock is the subclass and only a partial mock.
Use Mockito.mock(My.class, Answers.CALLS_REAL_METHODS), then mock any abstract methods that are invoked.
Example:
public abstract class My {
public Result methodUnderTest() { ... }
protected abstract void methodIDontCareAbout();
}
public class MyTest {
@Test
public void shouldFailOnNullIdentifiers() {
My my = Mockito.mock(My.class, Answers.CALLS_REAL_METHODS);
Assert.assertSomething(my.methodUnderTest());
}
}
Note: The beauty of this solution is that you do not have to implement the abstract methods. CALLS_REAL_METHODS causes all real methods to be run as is, as long as you don't stub them in your test.
In my honest opinion, this is neater than using a spy, since a spy requires an instance, which means you have to create an instantiable subclass of your abstract class.
Try using a custom answer.
For example:
import org.mockito.Mockito;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
public class CustomAnswer implements Answer<Object> {
public Object answer(InvocationOnMock invocation) throws Throwable {
Answer<Object> answer = null;
if (isAbstract(invocation.getMethod().getModifiers())) {
answer = Mockito.RETURNS_DEFAULTS;
} else {
answer = Mockito.CALLS_REAL_METHODS;
}
return answer.answer(invocation);
}
}
It will return the mock for abstract methods and will call the real method for concrete methods.