当前位置: 首页 > 知识库问答 >
问题:

PowerMock mockStatic未捕获模拟静态void方法调用

端木皓君
2023-03-14

我试图用PowerMock在Mockito上模拟一个静态void方法,但它并不是那么好用。

我的示例代码:

package com;

import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;

import com.BlackTempleTest.Illidan;

@RunWith(PowerMockRunner.class)
@PrepareForTest({ Illidan.class, EvilBrother.class })
public class BlackTempleTest {

    Answer<Object> defaultAnswer = new Answer<Object>() {
        @Override
        public Object answer(InvocationOnMock invocation) throws Throwable {
            System.out.println("Haha!");
            return null;
        }
    };

    @Test(expected = AssertionError.class)
    public void testIllidanFight() throws Exception {
        Illidan.startFight();
    }

    @Test
    public void testCheatOnIllidanFight() throws Exception {
        PowerMockito.mockStatic(Illidan.class, defaultAnswer);

        Illidan.startFight();
    }

    @Test(expected = AssertionError.class)
    public void testEvilBrotherFight() throws Exception {
        EvilBrother.startFight();
    }

    // dont work
    @Test
    public void testCheatOnEvilBrotherFight() throws Exception {
        PowerMockito.mockStatic(EvilBrother.class, defaultAnswer);

        EvilBrother.startFight();
    }

    static class Illidan {
        static void startFight() {
            Assert.fail("You are not prepared!");
        }
    }
}

EvilBrother.java

package com;

import com.BlackTempleTest.Illidan;

public class EvilBrother extends Illidan {

}

我的问题是,嵌套类按照预期的方式使用@PrepareForTest和PowerMockito.MockStatic组合进行了模拟,但是如果类在自己的类文件中,这些语句就不起作用了。

如何修复这个测试

    PowerMockito.doAnswer(defaultAnswer).when(EvilBrother.class, "startFight");

尽管执行了assert.fail,但可以通过Powermock管道传送错误的调用。

java.lang.AssertionError: You are not prepared!
    at org.junit.Assert.fail(Assert.java:88)
    at com.BlackTempleTest$Illidan.startFight(BlackTempleTest.java:54)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at org.powermock.reflect.internal.WhiteboxImpl.performMethodInvocation(WhiteboxImpl.java:1873)
    at org.powermock.reflect.internal.WhiteboxImpl.doInvokeMethod(WhiteboxImpl.java:773)
    at org.powermock.reflect.internal.WhiteboxImpl.invokeMethod(WhiteboxImpl.java:753)
    at org.powermock.reflect.Whitebox.invokeMethod(Whitebox.java:466)
    at org.powermock.api.mockito.internal.expectation.PowerMockitoStubberImpl.when(PowerMockitoStubberImpl.java:106)
    at com.BlackTempleTest.testCheatOnEvilBrotherFight(BlackTempleTest.java:47)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

共有1个答案

颜欣怡
2023-03-14

解决办法是,你必须嘲弄伊利丹而不是EvilBrother,即使你叫EvilBrother.startfight,因为方法是继承的。

@Test
public void testCheatOnEvilBrotherFight() throws Exception {
    PowerMockito.mockStatic(Illidan.class, defaultAnswer);

    EvilBrother.startFight();
}
 类似资料:
  • 我的C代码无法找到Java中的公共静态函数调用。它成功地找到了类,没有错误。 我试图将结果返回给回调方法。“5”稍后将被更复杂的内容取代。 我在StackOverflow上似乎也有类似的问题,但是到目前为止没有任何变化似乎有所帮助。也许我有逻辑错误? 我的JNI(更新#2): 此代码包含在此函数中调用的方法中: 我的Java(更新#1): 签名检查: javap-s-pcecutils 公共静态响

  • 在安装到AEM 5.6.1实例之前,我正在使用maven构建和测试我的代码。我已经编写了单元测试,这些测试使用wcm的实现从aem模拟中获益。io和其他需要使用powermockito模拟静态方法的单元测试。 以下是我对aem上下文、sling Mock和powermock的maven依赖关系。 在我的课堂上,我正在为aem上下文设置规则,并准备一些用于模拟的静态类: 当我通过命令行运行mvn测试

  • 问题内容: 我的代码中有一个静态方法,希望以某种方式进行模拟。 我正在使用jmock。 我想可以做到这一点的一种方法是在静态方法周围设置“包装类”并模拟该方法,但是我希望有一个更好的解决方案。 我要用这种错误的方式? 反馈: 我将要有一个接口和一个类,该接口和类具有一个仅称为静态方法的方法。这将允许我通过仅模拟对此包装器类的调用来模拟逻辑。(即使谈论它我也觉得很脏:)) 问题答案: 我们不支持在j

  • 实际的方法是在第3行被调用()。我已经添加了和注释。 为什么调用实际方法?我也尝试了PowerMockito.do返回,但是得到了同样的问题。

  • V4.2.0 新增 用法 释放所有文档资源,销毁内存占用,一般是在使用单列模式时,你需要调用此方法来手动释放资源占用。在非单列模式下,在使用完当前QueryList对象后,你应该调用destruct()方法来销毁当前QueryList对象。 背景:phpQuery 会将所有采集过的网页文档存到内存当中,不会主动释放文档,当涉及到大量的网页采集时,内存占用就会持续增加,最终导致内存溢出。手动调用此方

  • Powermock为什么不模拟静态方法调用,而是在然后()语句中调用初始方法? 在这种情况下,我有一系列方法调用: TestClass方法-调用- Class4方法尝试查找上下文中不存在且挂起的对象,因此我尝试使用Powermock模拟公共静态Class3方法。 所有的类和方法都是非最终的。我使用TestNg。我的测试方法有一个@准备测试我尝试了以下方法来模拟方法调用: 或而不是当-然后返回: 或