Mockito How to mock only the call of a method of the superclass

Viewed 148187

I'm using Mockito in some tests.

I have the following classes:

class BaseService {  
    public void save() {...}  
}

public Childservice extends BaseService {  
    public void save(){  
        //some code  
        super.save();
    }  
}   

I want to mock only the second call (super.save) of ChildService. The first call must call the real method. Is there a way to do that?

10 Answers

I found a way to suppress the superclass method using PowerMockito. 3 simple steps need for this

  1. Use PowerMockito.suppress method and MemberMatcher.methodsDeclaredIn method to supress parent class method

  2. Second add Parent class in @PrepareForTest

  3. Run your test class with PowerMock ie add @RunWith(PowerMockRunner.class) above your test class.

    @RunWith(PowerMockRunner.class)
    @PrepareForTest({BaseService.class})
    public class TestChildService(){
    
        @Spy
        private ChildService testChildServiceObj = Mockito.spy(new ChildService());
    
        @Test
        public void testSave(){
            PowerMockito.suppress(MemberMatcher.methodsDeclaredIn(BaseService.class));
    
            //your further test code
    
            testChildServiceObj.save();
        }
    }
    

Note: This will work only when the superclass method does not return anything.

You can do this with PowerMockito and replace behavior only of the parent class method with continuing testing the child's class method. Even when the method is returning some value, lets say a string, you can do something like this:

@RunWith(PowerMockRunner.class)
@PrepareForTest({ BaseService.class })
public class TestChildService() {

    private BasicService basicServiceObj;
    private ChildService testee;

    @Before
    public void init() {
        testee = new ChildService();
        basicServiceObj = PowerMockito.spy(new BaseService());
        PowerMockito.doReturn("Result").when(basicServiceObj, "save", ... optionalArgs);
    }

    @Test
    public void testSave(){
        testee.save();
    }
}

If you are returning nothing (void) then instead of doReturn you can use doNothing. Add some optionalArgs if the method have some arguments, if not, then skip that part.

There is simple approach that works for most of cases. You can spy your object and stub the method you want to mock.

Here is an example:

MyClass myObjectSpy = Mockito.spy(myObject);
org.mockito.Mockito.doReturn("yourReturnValue").when(mySpyObject).methodToMock(any()..);

So, when you test your object, you can use myObjectSpy and when methodToMock is called, it will overwrite the normal behavior by a mock method.

This code for a method with return. In case you have a void method you can use doNothing instead.

Related