我如何模拟一个静态方法,返回void PowerMock?

我的项目中有一些静态的util方法,其中一些只是传递或抛出exception。 这里有很多关于如何模拟一个返回types不是void的静态方法的例子。 但是,我怎样才能嘲笑一个静态方法返回无效只是“ doNothing() ”?

非void版本使用这些代码行:

 @PrepareForTest(StaticResource.class) 

 PowerMockito.mockStatic(StaticResource.class); 

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

但是,如果应用于返回voidStaticResources ,则编译将会抱怨when(T)不适用于void …

有任何想法吗?

一个解决方法可能只是让所有静态方法返回一些Boolean成功,但我不喜欢解决方法。

你可以像使用Mockito一样在真实实例上做到这一点。 比如你可以链接存根,下面这行会使第一个调用什么也不做,然后第二个和以后调用getResources会抛出exception:

 // 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的评论,请注意,如果在模拟创build时默认的回答没有改变,那么默认情况下,模拟将不会执行任何操作。 因此,编写下面的代码相当于不写它。

 doNothing().doThrow(Exception.class).when(StaticResource.class); StaticResource.getResource("string"); 

尽pipe如此,对于那些会阅读testing的同事来说,对于这个特定的代码来说,你什么也不期待。 当然,这可以根据testing的可理解性如何进行调整。


顺便说一句,在我的愚见你应该避免嘲笑静态代码,如果你正在制定新的代码。 在Mockito中,我们认为这通常是坏devise的一个暗示,可能会导致代码维护性差。 尽pipe现有的遗留代码是另一回事。

一般来说,如果你需要模拟私有或静态的方法,那么这个方法做的太多了,应该被外化在一个将被注入被测对象的对象中。

希望有所帮助。

问候

你可以像这样存根一个静态的无效方法:

 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(); 

简单来说,想象一下,如果你想模拟下线:

 StaticClass.method(); 

那么你写下面的代码行模拟:

 PowerMockito.mockStatic(StaticClass.class); PowerMockito.doNothing().when(StaticClass.class); StaticClass.method(); 

嘲笑一个静态方法,例如Fileutils.forceMKdir(File file),返回void Fileutils.forceMKdir(File file),

示例代码:

 File file =PowerMockito.mock(File.class); PowerMockito.doNothing().when(FileUtils.class,"forceMkdir",file);