简体   繁体   English

Powermock / EasyMock:对将引发异常的最终方法设置期望

[英]Powermock/EasyMock: Set expectation on final method that would throw exception

How do I set an expectation on a final method if I can't safely invoke that method at all? 如果根本无法安全地调用该方法,该如何对最终方法设置期望? PowerMock is supposed to ensure the invocation is mocked, but I can't even get to that stage: PowerMock应该确保调用被模拟,但是我什至不能进入那个阶段:

WithFinal.java: WithFinal.java:

public class WithFinal {
    public final void finalMethod() {
        throw new RuntimeException();
    }
}

CallsFinal.java: CallsFinal.java:

public class CallsFinal {
    private WithFinal withFinal;

    public CallsFinal(WithFinal withFinal) {
        this.withFinal = withFinal;
    }

    public void callFinal() {
        withFinal.finalMethod();
    }
}

PowerMockTest.java: PowerMockTest.java:

import org.easymock.EasyMock;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.modules.junit4.PowerMockRunner;
import org.powermock.core.classloader.annotations.PrepareForTest;

import static org.powermock.api.easymock.PowerMock.*;

@RunWith(PowerMockRunner.class)
@PrepareForTest(CallsFinal.class)
public class PowerMockTest {
    @Test public void testFinal() {
        WithFinal mock = createMock(WithFinal.class);
        CallsFinal callsFinal = new CallsFinal(mock);
        mock.finalMethod();
        EasyMock.expectLastCall().atLeastOnce();
        replay(mock);
        callsFinal.callFinal();
        verify(mock);
    }
}

I get a RuntimeException on the very first call to mock.finalMethod() , which makes sense, but I thought the whole point of PowerMock was to make this possible? 在第一次调用mock.finalMethod() ,我会收到一个RuntimeException ,这很有意义,但是我认为PowerMock的全部目的就是要实现这一点?

There was a simple mistake in the test class: instead of @PrepareForTest(CallsFinal.class) , it should have been @PrepareForTest(WithFinal.class) . 有一个在测试类一个简单的错误:不是@PrepareForTest(CallsFinal.class)它应该是@PrepareForTest(WithFinal.class)

PowerMock only requires that the calling class be prepared for test when mocking a system class from the JRE; 当从JRE模拟系统类时,PowerMock仅要求准备调用类以进行测试。 otherwise, it's the class to be mocked itself that needs to get prepared. 否则,需要准备的是要嘲笑的类。

Finally, I will mention there is another mocking library that can be used here, which I happen to develop: JMockit. 最后,我要提到的是我可以开发的另一个模拟库:JMockit。 With it, the test can be written as: 有了它,测试可以写成:

import org.junit.*;
import mockit.*;

public class JMockitTest {
    @Tested CallsFinal callsFinal;
    @Injectable WithFinal mock;

    @Test public void testFinal() {
        new Expectations() {{ mock.finalMethod(); }};

        callsFinal.callFinal();
    }
}

Using PowerMock, you can mock skip a internal method call instead of direct method call. 使用PowerMock,您可以模拟跳过内部方法调用而不是直接方法调用。

For example you want to test callFinal method of CallsFinal class which internally calling finalMethod of WithFinal class. 例如,您要测试内部调用WithFinal类的finalMethod的CallsFinal类的callFinal方法。 So in this case if you don't want to instantiate WithFinal class then you need to mock WithFinal object to skip internal call for finalMethod. 因此,在这种情况下,如果您不想实例化WithFinal类,则需要模拟WithFinal对象以跳过对finalMethod的内部调用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM