web-dev-qa-db-ja.com

PowerMockでvoidを返す静的メソッドをモックするにはどうすればよいですか?

私のプロジェクトには静的なutilメソッドがいくつかありますが、そのうちのいくつかは例外を渡すかスローするだけです。 void以外の戻り値の型を持つ静的メソッドをモックする方法については、多くの例があります。しかし、どうすればvoidを「doNothing()」に返す静的メソッドをモックできますか?

非voidバージョンは次のコード行を使用します。

_@PrepareForTest(StaticResource.class)
_

...

_PowerMockito.mockStatic(StaticResource.class);
_

...

_Mockito.when(StaticResource.getResource("string")).thenReturn("string");
_

ただし、StaticResourcesを返すvoidに適用すると、コンパイルはwhen(T)がvoidに適用できないと文句を言います...

何か案は?

回避策は、おそらくすべての静的メソッドが成功のためにいくつかのBooleanを返すようにすることですが、回避策は嫌いです。

56
Pete

実際のインスタンスでMockitoを使用する場合と同じ方法で実行できます。たとえば、スタブを連鎖させると、次の行は最初の呼び出しで何もせず、2回目以降の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では、通常それは悪い設計のヒントであり、保守性の低いコードにつながる可能性があると考えています。既存のレガシーコードもまた別の話です。

一般的に、プライベートメソッドまたは静的メソッドをモックする必要がある場合、このメソッドはあまりにも多くの処理を行うため、テスト対象オブジェクトに注入されるオブジェクトに外部化する必要があります。

お役に立てば幸いです。

よろしく

31
Brice

スタブ次のような静的voidメソッドを使用できます。

PowerMockito.doNothing().when(StaticResource.class, "getResource", anyString());

mockStatic(StaticResource.class)を呼び出すと、StaticResourceのすべての静的メソッドがデフォルトでスタブ化されるため、どうしてわざわざわざわざ入るのかわかりませんが

より便利なのは、次のようにStaticResource.getResource()に渡された値をキャプチャできることです。

ArgumentCaptor<String> captor = ArgumentCaptor.forClass(String.class);
PowerMockito.doNothing().when(
               StaticResource.class, "getResource", captor.capture());

次に、次のようにStaticResource.getResourceに渡された文字列を評価できます。

String resourceName = captor.getValue();
71
Justin Rowe

簡単に言えば、以下のモックが必要な場合を想像してください。

StaticClass.method();

次に、モックに以下のコード行を記述します。

PowerMockito.mockStatic(StaticClass.class);
PowerMockito.doNothing().when(StaticClass.class);
StaticClass.method();
11
Vivek HJ

たとえば、voidを返す静的メソッドをモックするにはFileutils.forceMKdir(File file),

サンプルコード:

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