我的项目中有一些静态的util方法,其中一些只是传递或抛出异常。关于如何模拟具有除void之外的返回类型的静态方法,有很多例子。但是,如何模拟一个将void返回到“doNothing()
”的静态方法?
非void版本使用以下代码行:
@PrepareForTest(StaticResource.class)
...
PowerMockito.mockStatic(StaticResource.class);
...
Mockito.when(StaticResource.getResource("string")).thenReturn("string");
但是,如果应用于返回StaticResources
的{{1}},则编译会抱怨void
不适用于无效...
有什么想法吗?
解决方法可能是让所有静态方法返回一些when(T)
以获得成功,但我不喜欢变通方法。
答案 0 :(得分:68)
你可以存根这样的静态void方法:
PowerMockito.doNothing().when(StaticResource.class, "getResource", anyString());
虽然我不确定你为什么会这么麻烦,因为当你调用 mockStatic(StaticResource.class)时,StaticResource中的所有静态方法都默认为stubbed
更有用,您可以捕获传递给 StaticResource.getResource()的值,如下所示:
ArgumentCaptor<String> captor = ArgumentCaptor.forClass(String.class);
PowerMockito.doNothing().when(
StaticResource.class, "getResource", captor.capture());
然后你可以像这样评估传递给StaticResource.getResource的String:
String resourceName = captor.getValue();
答案 1 :(得分:31)
你可以像在真实实例上使用Mockito一样进行。例如,您可以链接存根,以下行将使第一次调用不执行任何操作,然后第二次和将来调用getResources
将抛出异常:
// the stub of the static method
doNothing().doThrow(Exception.class).when(StaticResource.class);
StaticResource.getResource("string");
// the use of the mocked static code
StaticResource.getResource("string"); // do nothing
StaticResource.getResource("string"); // throw Exception
感谢Matt Lachman的评论,请注意,如果在模拟创建时未更改默认答案,则默认情况下模拟将不执行任何操作。因此,编写以下代码相当于不编写它。
doNothing().doThrow(Exception.class).when(StaticResource.class);
StaticResource.getResource("string");
尽管如此,对于那些阅读测试的同事来说,对于这个特定的代码没有任何期望,这可能会很有趣。当然,这可以根据测试的感知可理解性进行调整。
顺便说一句,在我的拙见中,如果你制作新的代码,你应该避免嘲笑静态代码。在Mockito,我们认为它通常暗示了糟糕的设计,可能会导致代码难以维护。虽然现有的遗留代码是另一个故事。
一般来说,如果你需要模拟私有或静态方法,那么这个方法做得太多,应该在一个将被注入测试对象的对象中外化。
希望有所帮助。
此致
答案 2 :(得分:11)
简单来说, 想象一下,如果你想在线下模拟:
StaticClass.method();
然后你写下面的代码行来模拟:
PowerMockito.mockStatic(StaticClass.class);
PowerMockito.doNothing().when(StaticClass.class);
StaticClass.method();
答案 3 :(得分:3)
模拟一个返回void的静态方法,例如Fileutils.forceMKdir(File file),
示例代码:
File file =PowerMockito.mock(File.class);
PowerMockito.doNothing().when(FileUtils.class,"forceMkdir",file);