Search code examples
javamockitopowermocksuper

Powermock - mocking a super method invocation


Here is my code -

import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.modules.junit4.PowerMockRunner;

import org.powermock.core.classloader.annotations.*;
import static org.powermock.api.support.SuppressCode.*;

class BaseService {
    public int save() {
        validate();
        return 2;
    }

    public static int save2() {
        return 5;
    }

    public void validate() {
        System.out.println("base service save executing...");
    }
}

class ChildService extends BaseService {
    public int save() {
        System.out.println("child service save executing...");
        int x = super.save2();
        int y = super.save();
        System.out.println("super.save returned " + y);
        load();
        return 1 + x;
    }

    public void load() {
        System.out.println("child service load executing...");
    }
}

@RunWith(PowerMockRunner.class)
@PrepareForTest(BaseService.class)
public class PreventSuperInvocation {

    @Test
    public void testSave() throws Exception {

        org.powermock.api.support.Stubber.stubMethod(BaseService.class,
                "save2", 4);
        suppressMethod(BaseService.class, "save");
        ChildService childService = new ChildService();
        System.out.println(childService.save());
    }

}

I would like to mock super.save() in ChildService class. But I can't find a way of doing it. suppressMethod() only suppresses and returns a default value (0 in the above case). And things like MemberModifier, Stubber, MethodProxy only work for static methods.

Is there a way of doing this in Powermock?

I'm using Powermock 1.5 and Mockito 1.9.5.


Solution

  • It seems that jMockit can do what I need. Maybe I will I post this question to the powermock mailing list. Meanwhile below should suffice. package learning_mocking_tools.learning_mocking_tools; package learning_mocking_tools.learning_mocking_tools;

    import mockit.*;
    
    import org.junit.Assert;
    import org.junit.Test;
    
    
    class BaseService {
        public int save() {
            validate();
            return 2;
        }
    
        public static int save2() {
            return 5;
        }
    
        public void validate() {
            System.out.println("base service save executing...");
        }
    }
    
    class ChildService extends BaseService {
        public int save() {
            System.out.println("child service save executing...");
            int x = super.save2();
            int y = super.save();
            System.out.println("super.save returned " + y);
            load();
            return 1 + y;
        }
    
        public void load() {
            System.out.println("child service load executing...");
        }
    }
    
    @MockClass(realClass = BaseService.class)
    class MockBase {
    
        @Mock
        public int save() {
            System.out.println("mocked base");
            return 9;
        }
    }
    
    public class PreventSuperInvocation {
    
        @Test
        public void testSave() throws Exception {
            MockBase mockBase = new MockBase();
            Mockit.setUpMock(BaseService.class, mockBase);
    
            ChildService childService = new ChildService();
    //      int x = childService.save();
    
            Assert.assertEquals(9 + 1, childService.save());
    
            Mockit.tearDownMocks();
        }
    
    }