1. ホーム
  2. java

[解決済み] パワーモッキートでstatic voidメソッドが呼び出されたことを確認する方法

2022-02-10 06:01:16

質問

下記を使用しています。

Powermock-mockito 1.5.12
Mockito 1.95
junit 4.11

以下は私のutilsクラスです。

public void InternalUtils {
    public static void sendEmail(String from, String[] to, String msg, String body) {
    }
}

テスト対象のクラスのgistです。

public class InternalService {
       public void processOrder(Order order) {
           if (order.isSuccessful()) {
               InternalUtils.sendEmail(...);
           }
       }
}

そして、これがテストです。

@PrepareForTest({InternalUtils.class})
@RunWith(PowerMockRunner.class)
public class InternalService {
   public void verifyEmailSend() {
        mockStatic(Internalutils.class);
        doNothing().when(InternalUtils, "sendEmail", anyString(), any(String.class), anyString(), anyString());
        Order order = mock(Order.class);
        when(order.isSuccessful()).thenReturn(true);
        InternalService is = new InternalService();

        verifyStatic(times(1));
        is.processOrder(order);
   }
}

上記のテストは失敗です。検証モードはnoneですが、コードによると、注文が成功した場合、メールが送信される必要があります。

解決するには?

動作をモックしている場合(例えば doNothing() を呼び出す必要はないはずです。 verify*() . とはいえ、あなたのテストメソッドを書き直すとしたら、以下のようになります。

@PrepareForTest({InternalUtils.class})
@RunWith(PowerMockRunner.class)
public class InternalServiceTest { //Note the renaming of the test class.
   public void testProcessOrder() {
        //Variables
        InternalService is = new InternalService();
        Order order = mock(Order.class);

        //Mock Behavior
        when(order.isSuccessful()).thenReturn(true);
        mockStatic(Internalutils.class);
        doNothing().when(InternalUtils.class); //This is the preferred way
                                               //to mock static void methods.
        InternalUtils.sendEmail(anyString(), anyString(), anyString(), anyString());

        //Execute
        is.processOrder(order);            

        //Verify
        verifyStatic(InternalUtils.class); //Similar to how you mock static methods
                                           //this is how you verify them.
        InternalUtils.sendEmail(anyString(), anyString(), anyString(), anyString());
   }
}

何が起こっているのかをよりよく強調するために、4つのセクションにグループ分けをしました。

1. 変数

インスタンス変数、メソッド引数、モックコラボレータはここで宣言することにしています。複数のテストで使用するものであれば、テストクラスのインスタンス変数にすることを検討してください。

2. モックの動作

ここでは、すべてのモックの動作を定義します。テスト対象のコードを実行する前に、ここで戻り値や期待値を設定することになります。一般に、ここでモックの振る舞いを設定しておけば、後でその振る舞いを検証する必要はありません。

3. 実行

ここでは何も派手なことはせず、テストされるコードをキックオフするだけです。私は、この部分に注意を喚起するために、独自のセクションを与えるのが好きです。

4. 検証

で始まるメソッドを呼び出したときです。 verify または assert . テストが終わったら、起こってほしいことが実際に起こったかどうかをチェックします。これが、私が見たこのテストメソッドの最大の間違いです。これは、メソッドの呼び出しが実行される前に検証しようとしたものです。その次に、あなたは どの 静的メソッドを検証したいのですね。

その他の注意事項

これは、ほとんど私の個人的な好みです。物事を行うには一定の順序が必要ですが、それぞれのグループ分けの中で、少し余裕があります。そうすることで、どこで何が起きているのかがすぐに分かるからです。

また、以下のサイトにあるサンプルは非常に堅牢で、必要なケースの大半に役立つので、ぜひ見てみることをお勧めします。