如何模拟使用PowerMock返回void的静态方法?

时间:2012-03-06 14:12:51

标签: static mocking mockito void powermock

我的项目中有一些静态的util方法,其中一些只是传递或抛出异常。关于如何模拟具有除void之外的返回类型的静态方法,有很多例子。但是,如何模拟一个将void返回到“doNothing()”的静态方法?

非void版本使用以下代码行:

@PrepareForTest(StaticResource.class)

...

PowerMockito.mockStatic(StaticResource.class);

...

Mockito.when(StaticResource.getResource("string")).thenReturn("string");

但是,如果应用于返回StaticResources的{​​{1}},则编译会抱怨void不适用于无效...

有什么想法吗?

解决方法可能是让所有静态方法返回一些when(T)以获得成功,但我不喜欢变通方法。

4 个答案:

答案 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);