如何使用 jmockit 从模拟的 class 调用真实方法

How to call a real method from a mocked class using jmockit

假设我有一个 class MockLoginHelper,我使用 jmockit 模拟了它。我想更改其中一种方法 getSDKConfig 的行为。在这个方法里面我想调用原来的LoginHelper.relogin。我的日食认为下面的 relogin(); 是未定义的。那么,如何从模拟的 class 中调用真正的方法?

class MockLoginHelper extends MockUp<LoginHelper> {
    @Tested
    private SDKConfiguration config;

    @Mock
    public SDKConfiguration getSDKConfig() {
        System.out.println("");
        System.out.println("Mocked " + this.getClass().getSimpleName());
        if (config == null) {
            try {
                relogin();
            } catch (Exception e) {
                System.err.println("failed to relogin");
                e.printStackTrace();
            }
        }
        return config;
    }
}

Java 编译器正确地认为 relogin 方法不在您模拟的 class 中,因为 MockLoginHelper 扩展了 MockUp class,而不是 LoginHelper class。你有两个选择。如果您想实际调用 LoginHelper 的实际实现,那么您需要实例化一个新实现:

class MockLoginHelper extends MockUp<LoginHelper> {
    @Tested
    private SDKConfiguration config;

    @Mock
    public SDKConfiguration getSDKConfig() {
        System.out.println("");
        System.out.println("Mocked " + this.getClass().getSimpleName());
        if (config == null) {
            try {
                LoginHelper helper = new LoginHelper();
                helper.relogin();
            } catch (Exception e) {
                System.err.println("failed to relogin");
                e.printStackTrace();
            }
        }
        return config;
    }
}

否则,您可以选择执行模拟实现并调用该模拟:

class MockLoginHelper extends MockUp<LoginHelper> {
    @Tested
    private SDKConfiguration config;

    @Mock
    public void relogin() {}

    @Mock
    public SDKConfiguration getSDKConfig() {
        System.out.println("");
        System.out.println("Mocked " + this.getClass().getSimpleName());
        if (config == null) {
            try {
                relogin();
            } catch (Exception e) {
                System.err.println("failed to relogin");
                e.printStackTrace();
            }
        }
        return config;
    }
}