Search code examples
javaunit-testingmockingabstract-classmockito

Using Mockito to test abstract classes


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?


Solution

  • 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.