単体テストでメソッド呼び出しをカウントする最良の方法は何ですか? それを許可するテストフレームワークはありますか?
7 に答える
.expects(1)
モック フレームワークが通常提供する型メソッドを使いたいと思うかもしれません。
リストをテストしていて、 clear が 3 回呼び出され、 add がこれらのパラメーターで少なくとも 1 回呼び出されたことを確認したい場合は、mockito を使用して、次のようにします。
List mock = mock(List.class);
someCodeThatInteractsWithMock();
verify(mock, times(3)).clear();
verify(mock, atLeastOnce()).add(anyObject());
ソース - MockitoVsEasyMock
Mockito では、次のようなことができます。
YourService serviceMock = Mockito.mock(YourService.class);
// code using YourService
// details of all invocations including methods and arguments
Collection<Invocation> invocations = Mockito.mockingDetails(serviceMock).getInvocations();
// just a number of calls of any mock's methods
int numberOfCalls = invocations.size();
Mockito の Answer インターフェイスを使用して、メソッド呼び出しの回数をカウントできます。
ConnectionPool mockedConnectionPool = mock(ConnectionPool.class);
final int[] counter = new int[1];
when(mockedConnectionPool.getConnection()).then(new Answer<Connection>() {
@Override
public Connection answer(InvocationOnMock invocation) throws Throwable {
counter[0]++;
return conn;
}
});
// some your code
assertTrue(counter[0] == 1);
カウントしたいメソッドに応じて@Before
、クラス/パッケージ/メソッドに一致するアドバイスを使用して、テスト構成を作成できます。
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
@Aspect
public class MethodCounterAspect {
private int counter = 0 // or inject the Counter object into this aspect
@Pointcut( "execution( * com.sample.your.package.*.*(..) )" )
public void methodsToCount() {}
@Before("methodsToCount()")
public void execute() throws Throwable {
counter++; // or update the counter injected into this aspect..
}
// get the counter
}
バニラの AspectJ または Spring AOP を上記または XML 構成を介して使用することができます。
必要に応じて、さまざまなポイントカット / アスペクトを作成できます。
テスト スパイが必要なようですね。たとえば、Mockito.spy()を参照してください。
いくつかのオプションがあります
1) 関数内の呼び出しをカウントする特別なコードを追加します。それは機能しますが、優れたソリューションではありません。
2) 単体テストを実行したら、コード カバレッジを確認します。ほとんどのカバレッジ ツールは呼び出しをカウントしますが、実際には後処理用に設計されています。
3) プロファイラーを使用します。プロファイラーを使用すると、関数が呼び出された回数をカウントできます。これは非常に手動のプロセスであるため、実際には単体テスト用には設計されていません。
より良い解決策は、出力が内部でどのように機能するかを確認するのではなく、出力が期待どおりであることを確認することです。