多くのモックフレームワークは、モックとスタブの概念を、機能的にほぼ同じと見なすことができるように、ますます近づけています。ただし、概念的な観点から、私は通常、この規則に従うようにしています。
- モック:テスト対象のオブジェクトの動作を明示的に検証しようとしている場合のみ(つまり、テストでは、このオブジェクトがそのオブジェクトを呼び出す必要があると言っている場合)。
- スタブ:いくつかの機能/動作をテストしようとしているが、それを機能させるには、いくつかの外部オブジェクトに依存する必要があります(つまり、テストでは、このオブジェクトは何かを実行する必要があると言っていますが、副作用として、そのオブジェクト)
これは、各単体テストが1つのことだけをテストすることを確認するとより明確になります。確かに、1つのテストですべてをテストしようとすると、すべてを期待することもできます。しかし、特定の単体テストがチェックしていることだけを期待することで、テストの目的が一目でわかるため、コードがはるかに明確になります。
これのもう1つの利点は、変更からわずかに隔離され、変更によって中断が発生した場合のエラーメッセージが改善されることです。言い換えると、実装の一部を微妙に変更すると、テストケース全体が壊れてノイズが発生するのではなく、テストケースが1つだけ壊れて、何が壊れているかが正確に示される可能性が高くなります。
編集:電卓オブジェクトがデータベースへのすべての追加を(擬似コードで)監査するという不自然な例に基づいて、より明確になる可能性があります...
public void CalculateShouldAddTwoNumbersCorrectly() {
var auditDB = //Get mock object of Audit DB
//Stub out the audit functionality...
var calculator = new Calculator(auditDB);
int result = calculator.Add(1, 2);
//assert that result is 3
}
public void CalculateShouldAuditAddsToTheDatabase() {
var auditDB = //Get mock object of Audit DB
//Expect the audit functionality...
var calculator = new Calculator(auditDB);
int result = calculator.Add(1, 2);
//verify that the audit was performed.
}
したがって、最初のテストケースでは、Add
メソッドの機能をテストしており、監査イベントが発生するかどうかは関係ありませんが、電卓はauditDB参照がないと機能しないことがわかっているため、スタブするだけです。特定のテストケースを機能させるための最小限の機能を提供します。2番目のテストでは、を実行すると監査イベントが発生することを具体的にテストしているAdd
ため、ここでは期待値を使用します(テスト対象ではないため、結果が何であるかは気にしないことに注意してください)。
はい、2つのケースを1つにまとめて、期待を実行し、結果が3であると主張することもできますが、1つの単体テストで2つのケースをテストしています。これにより、テストがより脆弱になり(テストを中断するために変更される可能性のあるものの表面積が大きくなるため)、明確ではなくなります(マージされたテストが失敗した場合、問題が何であるかがすぐにはわかりません。追加が機能しないため、または監査が機能していませんか?)