Powermock - 模拟超级方法调用

5

这是我的代码 -

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());
    }

}

我想在ChildService类中模拟super.save()方法的调用,但我找不到实现的方法。suppressMethod() 方法只能抑制并返回默认值(在上面的情况中为0)。而像MemberModifier、Stubber、MethodProxy这样的方法只适用于静态方法。
在Powermock中有没有方法可以实现这个功能呢?
我正在使用Powermock 1.5和Mockito 1.9.5。

1
对我而言,这种情况告诉我要使用组合而不是继承!这很可能会导致更好的面向对象设计。因此,我甚至不会尝试使用powermock来实现它,它就像是在编写传统代码! - bric3
2
请参见以下链接:https://dev59.com/m3A75IYBdhLWcg3wH1JB - Icarus3
1
除了https://dev59.com/m3A75IYBdhLWcg3wH1JB之外,了解PowerMock是否可以做到这一点将是有趣的。 - iwein
1个回答

0

看起来jMockit可以满足我的需求。也许我会在powermock邮件列表中发布这个问题。同时下面的代码应该就足够了。 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();
    }

}

注意:jMockit在1.4版本中(自2013年8月起)删除了@MockClass(realClass)注释。 - jrg

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接