Question
How can I test abstract classes using the Mockito framework without manually creating mocks?
@RunWith(MockitoJUnitRunner.class)
public abstract class AbstractService {
public abstract int calculate(int a, int b);
}
public class ConcreteService extends AbstractService {
@Override
public int calculate(int a, int b) {
return a + b;
}
}
@Test
public void testAbstractClassMethod() {
ConcreteService service = Mockito.mock(ConcreteService.class);
Mockito.when(service.calculate(3, 2)).thenReturn(5);
assertEquals(5, service.calculate(3, 2));
}
Answer
Testing abstract classes in Java can be challenging, especially when you want to avoid manually creating concrete implementations. Mockito provides a convenient way to create mock instances of abstract classes, allowing you to focus on testing the behavior of your code without the overhead of additional implementation details.
Mockito.mock(AbstractService.class);
Mockito.when(mockService.calculate(1, 2)).thenReturn(3);
int result = mockService.calculate(1, 2);
assertEquals(3, result);
Causes
- Abstract classes cannot be instantiated directly, which complicates testing individual methods.
- Manually creating concrete subclasses can lead to duplicated code and maintenance issues.
Solutions
- Utilize Mockito’s ability to create mock instances of abstract classes.
- Override specific methods in the mock to define expected behavior for the test.
Common Mistakes
Mistake: Forgetting to add @RunWith(MockitoJUnitRunner.class) to the test class.
Solution: Ensure your test class is running with the Mockito test runner to enable annotations.
Mistake: Attempting to mock final classes or methods, which Mockito cannot mock.
Solution: Use a concrete subclass or alternative testing strategy for final classes.
Helpers
- Mockito
- test abstract classes
- Mockito testing guide
- Java testing frameworks
- mockito mock abstract class