尝试让 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 报告,我看到了这一点:
我看过:
- How to mock a void static method to throw exception with Powermock?
- Powermock/mockito does not throw exception when told to
- PowerMockito mock static method which throws exception
- https://github.com/jayway/powermock/wiki/MockitoUsage#how-to-stub-void-static-method-to-throw-exception
- http://www.johnmullins.co/blog/2015/02/15/beginners-guide-to-using-mockito-and-powermockito-to-unit-test-java/
我还是完全迷失了。我不知道是否需要触发 IOException
或者是否可以在不使用 doThrow
的情况下验证 handleException
的输出。谁来帮忙啊!
错误日志:
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
最佳答案
我的建议:忘记使用 PowerMock。
如果您必须模拟静态方法,请围绕它构建您自己的小包装类。然后,为了进行测试,您的包装器可以返回您控制的内容;以及用于生产用途;你的包装器只调用静态方法。
PowerMock 看起来可以解决很多问题;但迟早它会导致更多问题。它破坏了覆盖范围,使更改底层 JVM 变得更加困难,等等。
说真的:如果您的设计只能使用 PowerMock 进行测试,这通常清楚地表明您的设计糟糕。所以:专注于重新编写被测代码;而不是把时间投入到像 PowerMock 这样弊大于利的工具上。
我花了无数时间试图解决 PowerMock 问题;自从我开始编写“更好地测试”生产代码以来......我已经编写了数百或数千个测试,而不再需要 PowerMock。
就您的情况而言:首先要避免各处静电。基本上,您可以通过(最坏的情况)在必须进行的静态调用周围拉一些包装类来实现这一点。为了进行测试,您可以模拟包装对象;在生产代码中,您使用依赖项注入(inject)来提供一个(单例/枚举)包装器对象,该对象仅进行静态调用。
关于java - 最终类上的 PowerMock UnfinishedStubbingException 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37291052/