web-dev-qa-db-ja.com

テスト中のクラスのモッククラス

テスト中のクラスの他のクラスをMockitoでモックするにはどうすればよいですか?

例えば:

MyClass.Java

_class MyClass {
    public boolean performAnything() {
        AnythingPerformerClass clazz = new AnythingPerformerClass();
        return clazz.doSomething();        
    }
}
_

AnythingPerformerClass.Java

_class AnythingPerformerClass {
    public boolean doSomething() {
        //very very complex logic
        return result;
    }
}
_

そしてテスト:

_@Test
public void testPerformAnything() throws Exception {
    MyClass clazz = new MyClass();
    Assert.assertTrue(clazz.performAnything());
}
_

AnythingPerformerClassから不要なロジックを除外するためにAnythingPerformerClassをスプーフィングできますか? trueまたはfalseを返すためにdoSomething()メソッドをオーバーライドできますか?

Mockitoを指定する理由は、Android Robolectricでのテストに必要なためです。

17
NikedLab

dependency injection を使用するようにMyClassをリファクタリングできます。 AnythingPerformerClassインスタンスを作成する代わりに、クラスのインスタンスをMyClassのコンストラクターに渡すことができます。

class MyClass {

   private final AnythingPerformerClass clazz;

   MyClass(AnythingPerformerClass clazz) {
      this.clazz = clazz;
   }

   public boolean performAnything() {         
     return clazz.doSomething();        
   }
}

その後、単体テストでモック実装を渡すことができます

@Test
public void testPerformAnything() throws Exception {
   AnythingPerformerClass mockedPerformer = Mockito.mock(AnythingPerformerClass.class);
   MyClass clazz = new MyClass(mockedPerformer);
   ...
}

または、AnythingPerformerClassに状態が含まれている場合は、AnythingPerformerClassBuilderをコンストラクターに渡すことができます。

16
cyon

現在のところ(メソッド内のAnythingPerformerClassの宣言とインスタンス化の両方で、Mockitoのみを使用してAnythingPerformerClassをモックすることはできません。

可能であれば、AnythingPerformerClassの宣言とインスタンス化の両方をクラスレベルに移動します。タイプAnythingPerformerClassのインスタンス変数を宣言し、コンストラクターでインスタンス化します。

そうすれば、テスト中にAnythingPerformerClassのモックをより簡単に挿入し、その動作を指定できます。例えば:

when(anythingPerformerClassMock.doSomething()).thenReturn(true);

またはエラー処理をテストするには:

when(anythingPerformerClassMock.doSomething()).thenTrow(new NullPointerException());
3
mthmulders

Mockitoで何を返すかを設定できます。

when(mock.method()).thenReturn(someValue)
0
mokuril