web-dev-qa-db-ja.com

PowerMockitoは単一の静的メソッドをモックし、オブジェクトを返す

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の両方を呼び出しており、m1とm2の戻り型は異なるため、戻り型の不一致エラーが発生します。

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

3)PowerMockito.mockPartial(Static.class, "m1");は、mockPartialが利用できないというコンパイラエラーを示します。これは http://code.google.com/p/powermock/wiki/MockitoUsage から取得しました。

80
user1393653

あなたがしたいことは、1の一部と2のすべての組み合わせです。

クラスのすべての静的メソッドに対して、enable静的モックにPowerMockito.mockStaticを使用する必要があります。これは、when-thenReturn構文を使用してスタブすることをpossibleにすることを意味します。

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

javadoc から:

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

defaultデフォルトのスタブ戦略は、オブジェクト、数値、およびブール値のメソッドに対してnull、0またはfalseを返すだけです。 2-argオーバーロードを使用すると、「いいえ、いいえ、いいえ、デフォルトではこのAnswerサブクラスの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());
  }
}

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

115
Tom Tresansky