Mocking abstract classes

This post explain mocking abstract classes for testing purposes.

Note

1) This feature is not available in pre 1.10.12 release
2) We can mock abstract class only if it has parameter less constructor

Below is the example of how we can do it.

ClassA (Abstract Class)


package package2;

public abstract class ClassA {
    public abstract int method1();
    
    public int method2() {
        return 1;
    }
}

ClassB (Base Class)


package package2;

public class ClassB extends ClassA {
    @Override
    public int method1() {
        return 2;
    }
}

Class1 (Main class that uses ClassA)


package package2;

public class Class1 {
    private ClassA classA;
    
    public int method1() {
        return classA.method1();
    }

    public int method2() {
        return classA.method2();
    }
    
    public ClassA getClassA() {
        return classA;
    }

    public void setClassA(ClassA classA) {
        this.classA = classA;
    }
}

Test Class


1  package package2;
2  
3  import org.junit.Test;
4  import org.junit.runner.RunWith;
5  import org.mockito.InjectMocks;
6  import org.mockito.Mockito;
7  import org.mockito.runners.MockitoJUnitRunner;
8  
9  import static org.junit.Assert.*;
10 import static org.mockito.Mockito.*;
11 
12 @RunWith(MockitoJUnitRunner.class)
13 public class Class1Test {
14  @InjectMocks
15  private Class1 class1;
16  
17  @Test
18  public void testMethod1() {
19      ClassA classA = Mockito.mock(ClassA.class, Mockito.withSettings().useConstructor().defaultAnswer(Mockito.RETURNS_SMART_NULLS));
20      
21      when(classA.method1()).thenReturn(5);
22      when(classA.method2()).thenReturn(6);
23      
24      class1.setClassA(classA);
25      
26      assertEquals(5,class1.method1());
27      assertEquals(6,class1.method2());
28  }
29 }

Explanation

The below code snippet present at line 19 in the test code

Mockito.withSettings().useConstructor().defaultAnswer(Mockito.RETURNS_SMART_NULLS)

creates a MockitoSettings instance
1) which should use abstract class’s constructor to create future mock instance
2) and should set the default answer of all the method in the mock to return appropriate default values.

We pass the MockitoSettings instance as a parameter to Mockito.mock method along with the class to mock. Refer to line 19.

Leave a Reply