PowerMockitoモック単一静的メソッドとオブジェクトを返す


98

2つの静的メソッドm1とm2を含むクラスから静的メソッドm1をモックしたい。そして、私はメソッドm1がオブジェクトを返すことを望みます。

私は以下を試しました

1)

PowerMockito.mockStatic(Static.class, new Answer<Long>() {
         @Override
         public Long answer(InvocationOnMock invocation) throws Throwable {
            return 1000l;
         }
      });

これは、戻り値の型が異なるm1とm2の両方を呼び出すため、戻り値の型の不一致エラーが発生します。

2)PowerMockito.when(Static.m1(param1, param2)).thenReturn(1000l); しかし、これはm1が実行されるときに呼び出されません。

3)http://code.google.com/p/powermock/wiki/MockitoUsagePowerMockito.mockPartial(Static.class, "m1"); から取得したmockPartialが利用できないというコンパイラエラーが発生します

回答:


135

やりたいことは、1の一部と2のすべての組み合わせです。

クラスのすべての静的メソッドの静的モッキングを有効にするには、PowerMockito.mockStaticを使用する必要があります。つまり、when-thenReturn構文を使用してそれらをスタブ化できるようになります。

しかし、使用しているmockStaticの2引数のオーバーロードは、モックインスタンスで明示的にスタブしていないメソッドを呼び出したときにMockito / PowerMockが実行する必要があるデフォルトの戦略を提供します。

javadocから:

インタラクションへの答えのために指定された戦略でクラスのモックを作成します。これは非常に高度な機能であり、通常、適切なテストを作成するために必要はありません。ただし、レガシーシステムで作業する場合に役立ちます。これはデフォルトの回答であるため、メソッド呼び出しをスタブしない場合にのみ使用されます。

デフォルトの戦略をスタブデフォルトでは、オブジェクト、数、およびboolean型高く評価方法のためだけのリターンはnull、0またはfalseにあります。2引数のオーバーロードを使用することで、「いいえ、いいえ、いいえ、デフォルトではこのAnswerサブクラスを使用して」デフォルト値を取得するための応答メソッドです。これはLongを返すため、互換性のないものを返す静的メソッドがある場合長い間、問題があります。

代わりに、1引数バージョンのmockStaticを使用して静的メソッドのスタブを有効にし、次にwhen-thenReturnを使用して特定のメソッドに対して何を実行するかを指定します。例えば:

import static org.mockito.Mockito.*;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;

class ClassWithStatics {
  public static String getString() {
    return "String";
  }

  public static int getInt() {
    return 1;
  }
}

@RunWith(PowerMockRunner.class)
@PrepareForTest(ClassWithStatics.class)
public class StubJustOneStatic {
  @Test
  public void test() {
    PowerMockito.mockStatic(ClassWithStatics.class);

    when(ClassWithStatics.getString()).thenReturn("Hello!");

    System.out.println("String: " + ClassWithStatics.getString());
    System.out.println("Int: " + ClassWithStatics.getInt());
  }
}

文字列値の静的メソッドは「Hello!」を返すようにスタブされますが、整数値の静的メソッドはデフォルトのスタブを使用して0を返します。


1
再生する必要はありませんか?
Balaji Boggaram Ramanarayan 2014

うーん...ソルタはそうみたいです。たぶん、PowerMockitoがPowerMockを再生しますか?それも気になります。
djangofan 2015年

3
しかし、静的メソッドが正確な引数で呼び出されることを確認する必要がある場合はどうなりますか?
elTomato 2016年

6
@PrepareForTest注釈はクラスでなければなりません呼び出す静的メソッドではなく、静的なメソッドがあるクラスを。
Hazel Troost 2017

5
@HazelTroost-いいえ、OPは正しいです。テスト用に準備する必要があるのは、静的メソッドを含むクラスです。そう@PrepareForTest(ClassWithStatics.class)です。
arry36
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.