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

最终类上的PowerMock UnfinishedStubbingException错误

宁良平
2023-03-14

试图让Mockito和PowerMock正常运行,但在尝试运行以下代码时,我得到了UnfinishedStubbingException:

@RunWith(PowerMockRunner.class)
@PrepareForTest(FileIOHelper.class)
public class FileIOHelperTest {

    @Test
    public void testIOExceptionOnWrite() {
        PowerMockito.mockStatic(FileIOHelper.class);
        PowerMockito.doThrow(new IOException()).when(FileIOHelper.class);
        PowerMockito.verifyStatic();
        FileIOHelper.write(Mockito.anyString(), Mockito.anyString());
    }

    @After
    public void validate() {
        Mockito.validateMockitoUsage();
    }

}

而这个IO类

public final class FileIOHelper {

    public static void write(final String file, String message, final boolean appendNewLine) {
        if(checkArgs(file, message)) {
            final Path path = Paths.get(file);
            StandardOpenOption mode = StandardOpenOption.APPEND;
            if(Files.notExists(path)) {
                mode = StandardOpenOption.CREATE_NEW;
            }
            if(appendNewLine) {
                message += System.getProperty("line.separator");
            }
            try {
                Files.write(path, message.getBytes(), mode);
            } catch(IOException e) {
                handleException(e, "Problem writing to " + file);
            }
        }
    }

    private static boolean checkArgs(final String... args) {
        if(args != null && args.length > 0) {
            for(final String arg : args) {
                if(arg == null || arg.isEmpty()) {
                    return false;
                }
            }
        }

        return true;
    }

    private static void handleException(final IOException e, final String errorMsg) {
        handleException(e, errorMsg, true);
    }

    private static void handleException(final IOException e, final String errorMsg, final boolean printStace) {
        checkArgs(errorMsg);

        System.err.println(errorMsg);
        System.err.println(e.getMessage());

        if(printStace) {
            e.printStackTrace();
        }
    }

}

我想要做的是以某种方式触发IOException,以便可以测试HandleException。为什么有人会问?我在看我的Jacoco报告,我看到了这个:

    null
org.mockito.exceptions.misusing.UnfinishedStubbingException: 
Unfinished stubbing detected here:
-> at FileIOHelperTest.testIOExceptionOnWrite(FileIOHelperTest.java:8) // doThrow line

E.g. thenReturn() may be missing.
Examples of correct stubbing:
    when(mock.isOk()).thenReturn(true);
    when(mock.isOk()).thenThrow(exception);
    doThrow(exception).when(mock).someVoidMethod();
Hints:
 1. missing thenReturn()
 2. you are trying to stub a final method, you naughty developer!
 3: you are stubbing the behaviour of another mock inside before 'thenReturn' instruction if completed

共有1个答案

陈高寒
2023-03-14

我的建议:忘记使用PowerMock。

如果您必须模拟静态方法,那么围绕它构建您自己的小包装类。然后,为了进行测试,您的包装器可以返回您控制的内容;和生产用途;包装器只调用静态方法。

PowerMock看起来是许多问题的解决方案;但它迟早会成为更多问题的原因。它打破了覆盖范围,使底层JVM更难更改,等等。

 类似资料:
  • 问题内容: 我有一个很简单的问题: 我想要一个Java类,该类提供一个公共静态方法,该方法可以执行某些操作。这只是出于封装目的(将所有重要的内容都放在一个单独的类中)… 此类不应被实例化或扩展。那让我写道: (尽管我知道,这是禁止的)。 我也知道,我可以使此类完全为final,并在将其私有化时覆盖标准构造函数。 但这在我看来更像是一种“解决方法”,应该更可能由最终的抽象类完成… 而且我讨厌解决方法

  • 问题内容: 我正在尝试将java8 forEach循环内的布尔变量更改为true,这是非最终的。但是我遇到了以下错误:在封闭范围内定义的必需局部变量必须是final或有效的final。 如何解决这个错误? 代码: 这是我在函数中创建的变量。 现在,当我尝试更改它时: 我收到错误消息:封闭范围中定义的必需局部变量必须是final或有效的final。 为什么会出现此错误,以及如何解决? 问题答案: 您

  • 类型参数T不应由最终的类型整数限定。不能进一步扩展Final类型 为什么使用final类型作为通配符的上限完全可以,但对类型参数抛出警告?为什么Java甚至允许通配符被最终的上层类型所约束?

  • 问题内容: 我的问题很简单: 编译器是否将final类中的所有方法都视为final本身?将关键字添加到最终类中的方法是否有效果? 我知道最终方法更有可能被内联,这就是我要问的原因。 提前致谢。 问题答案: 没错,final类中的所有方法都隐式为final。 看这里: “请注意,您也可以将整个类声明为final。声明为final的类不能被子类化。例如,在创建不可变类(如String类)时,这特别有用

  • 假设我运行了一个带有ErrorAction Stop的命令,它生成了一个错误。我想知道错误最初是否终止?我有ErrorVariable或$Error对象。ErrorVariable能捕捉两种错误吗?我正在寻找一处房产。NET/PowerShell对象,它可以告诉我这个错误正在终止。非终止错误也会产生异常吗? 另外,当我在控制台上写一个命令时(不是ISE也没有运行脚本,只是在控制台上写一个命令),我