79

プロジェクトにいくつかの静的utilメソッドがあり、そのうちのいくつかは単に例外を渡すかスローします。void以外のreturn型を持つ静的メソッドをモックする方法については多くの例があります。しかし、voidを単に ""に返す静的メソッドをどのようにモックできますdoNothing()か?

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

@PrepareForTest(StaticResource.class)

..。

PowerMockito.mockStatic(StaticResource.class);

..。

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

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

何か案は?

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

4

4 に答える 4

89

次のような静的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();
于 2013-07-02T08:10:24.717 に答える
45

Mockito 3.4.0以降、静的メソッドをモックするための実験的なAPIが導入されました。

次のサンプルコードは、Mockito 4.3.1(testImplementation("org.mockito:mockito-inline:4.3.1)、およびJUnit Jupiter 5.8.2、OpenJDK11でテストされています。

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.mockito.MockedStatic;
import org.mockito.Mockito;

import java.util.UUID;

public class StaticMockTest {

    @Test
    void showCaseStaticMock() {
        try (MockedStatic<StaticMockTest> staticMock = Mockito.mockStatic(StaticMockTest.class)) {
            staticMock.when(StaticMockTest::getUUIDValue).thenReturn("Mockito");
            Assertions.assertEquals("Mockito", StaticMockTest.getUUIDValue());
        }

        // Regular UUID
        UUID.fromString(StaticMockTest.getUUIDValue());
    }

    public static String getUUIDValue() {
        return UUID.randomUUID().toString();
    }
}

前の回答、おそらくMockito 1.x/2.xとPowermock1.x/ 2.x

実際のインスタンスで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では、これは通常、悪い設計のヒントであり、保守性の低いコードにつながる可能性があると考えています。既存のレガシーコードはさらに別の話ですが。

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

お役に立てば幸いです。

よろしく

于 2012-03-06T14:30:49.363 に答える
19

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

StaticClass.method();

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

PowerMockito.mockStatic(StaticClass.class);
PowerMockito.doNothing().when(StaticClass.class);
StaticClass.method();
于 2015-05-04T12:30:54.080 に答える
7

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

サンプルコード:

File file =PowerMockito.mock(File.class);
PowerMockito.doNothing().when(FileUtils.class,"forceMkdir",file);
于 2016-07-07T08:09:34.377 に答える