次のようなFizzConfigurator
クラスの単体テストを作成しています。
_public class FizzConfigurator {
public void doFoo(String msg) {
doWidget(msg, Config.ALWAYS);
}
public void doBar(String msg) {
doWidget(msg, Config.NEVER);
}
public void doBuzz(String msg) {
doWidget(msg, Config.SOMETIMES);
}
public void doWidget(String msg, Config cfg) {
// Does a bunch of stuff and hits a database.
}
}
_
doWidget(String,Config)
メソッドをスタブ化する簡単な単体テストを記述したいのですが(実際には起動せず、データベースにヒットしません)、これによりverifyができますdoBuzz(String)
を呼び出すと、doWidget
が実行されます。 Mockitoは、ここでの仕事に適したツールのようです。
_public class FizzConfiguratorTest {
@Test
public void callingDoBuzzAlsoCallsDoWidget() {
FizzConfigurator fixture = Mockito.spy(new FizzConfigurator());
Mockito.when(fixture.doWidget(Mockito.anyString(), Config.ALWAYS)).
thenThrow(new RuntimeException());
try {
fixture.doBuzz("This should throw.");
// We should never get here. Calling doBuzz should invoke our
// stubbed doWidget, which throws an exception.
Assert.fail();
} catch(RuntimeException rte) {
return; // Test passed.
}
}
}
_
これはらしい(少なくとも私にとっては)良いゲームプランのようです。しかし、実際にコードを記述しようとすると、テストメソッド内の2行目(Mockito.when(...)
行)で次のコンパイラエラーが発生します。
Mockito型のwhen(T)メソッドは引数に適用できません(void)
Mockitoがvoid
を返すメソッドをモックできないことがわかりました。だから私は尋ねます:
doBuzz
が内部でdoWidget
を呼び出す、より良い、Mockito推奨のテスト方法はありますか?そしてdoWidget
クラス全体の中で最も重要なメソッドであるため、FizzConfigurator
のモック/スタブについて何ができますか?これをテストするために例外を使用するのではなく、検証を使用します。もう1つの問題は、voidを返すメソッドでwhen()
を使用できないことです。
ここに私がそれをする方法があります:
FizzConfigurator fixture = Mockito.spy(new FizzConfigurator());
doNothing().when(fixture).doWidget(Mockito.anyString(), Mockito.<Config>any()));
fixture.doBuzz("some string");
Mockito.verify(fixture).doWidget("some string", Config.SOMETIMES);
これは、doWidget
メソッドがFizzConfigurator
が依存する別のクラスに属すべきであることを明確に示しています。
テストでは、この新しい依存関係はモックであり、そのメソッドがverify
で呼び出されたかどうかを簡単に確認できます。
私の場合、スタブを作成しようとしていた方法で、誤ったマッチャーを渡していました。
私のメソッドシグネチャ(スタブしようとしていたスーパークラスメソッドの場合):文字列、オブジェクト。
私は通りました:
myMethod("string", Mockito.nullable(ClassType.class))
および取得:
Hints: 1. missing thenReturn() 2. you are trying to stub a final method, which is not supported 3: you are stubbing the behaviour of another mock inside before 'thenReturn' instruction if completed
別のパラメーターでマッチャーを使用する場合は、文字列にもマッチャーを使用する必要があります。
myMethod(eq("string"), Mockito.nullable(ClassType.class))
お役に立てれば!