How to trick a protected subclass method inherited from an abstract class?

How to use Mockito or PowerMock to mock a protected method implemented by a subclass, but inherited from an abstract superclass?

In other words, I want to test the doSomething method by making fun of "doSomethingElse".

Abstract superclass

public abstract class TypeA { public void doSomething() { // Calls for subclass behavior doSomethingElse(); } protected abstract String doSomethingElse(); } 

Subclass implementation

 public class TypeB extends TypeA { @Override protected String doSomethingElse() { return "this method needs to be mocked"; } } 

Decision

The answers given here are correct and will work if the participating classes are in the same package.

But if different packages are involved, one of them is for the PowerMock user. The following example worked for me. Of course, there may be other ways to do this, it works.

 import static org.junit.Assert.assertEquals; import org.junit.Test; import org.junit.runner.RunWith; import org.powermock.api.mockito.PowerMockito; import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.modules.junit4.PowerMockRunner; @RunWith(PowerMockRunner.class) @PrepareForTest({ TypeB.class }) public class TestAbstract { @Test public void test_UsingPowerMock() throws Exception { // Spy a subclass using PowerMock TypeB b = PowerMockito.spy(new TypeB()); String expected = "some value for mock"; // Mock a method by its name using PowerMock again PowerMockito.doReturn(expected).when(b, "doSomethingElse"); // Calls the String actual = b.doSomething(); assertEquals(expected, actual); } } 

Note. Tests are performed using Java 5, jUnit 4.11, Mockito 1.9.0, and PowerMock 1.4.12.

+5
source share
4 answers

You can use Mockito.CALLS_REAL_METHODS to mock an abstract method. This will call the original methods of the class, and you can mock all abstract methods yourself.

 TypeA typeA = mock(TypeA.class, Mockito.CALLS_REAL_METHODS); when(typeA.doSomethingElse()).thenReturn("Hello"); typeA.doSomething(); 

Or you check directly on TypeB with a spy:

 TypeB typeB = spy(new TypeB()); when(typeB.doSomethingElse()).thenReturn("Hello"); typeB.doSomething(); 
+5
source

I suggest using Mockito for this:

 // Create a new Mock final TypeA a = Mockito.mock(TypeA.class, Mockito.CALLS_REAL_METHODS); // Call the method a.doSomething(); // Now verify that our mocked class' method was called Mockito.verify(a, Mockito.times(1)).doSomethingElse(); 
+4
source

You can check your abtract class with mockito as follows.

 TypeA typA = Mockito.mock(TypeA.class, Mockito.CALLS_REAL_METHODS); when(typA.doSomethingElse()).thenReturn("doSomethingElse"); Assert.assertSomething(typeA.doSomething()); 
+3
source

To mock methods that return void in abstract classes, we could use:

 MyAbstractClass abs = Mockito.mock(MyAbstractClass.class); Mockito.doNothing().when(abs).myMethod(arg1,arg2....)); 

We can replace the arguments with Mockito.anyString (), etc. as required.

+2
source

All Articles