頭のてっぺんから:IsNew
プロパティが読み取られていることを確認します。
var mock = new Mock<MyObj>();
mock.Setup(m => m.IsNew).Returns(true).Verifiable();
//...
sut.Save(mock.Object);
//...
mock.Verify();
上記の例では、IsNew
プロパティがを返すtrue
ため、作成パスが使用されます。
CreateメソッドまたはUpdateメソッドのいずれかが呼び出されたことを確認するには、その機能にフックする必要があります。リポジトリは静的クラスのようです。この場合、テストダブルに置き換えることはできませんが、コードを間違った方法で読み取っている可能性があります...テストダブル(モック)に置き換えることができる場合は、上で概説したのと同じ原理を使用できます。
Saveメソッドが呼び出された後にリポジトリの状態を調べることができる場合は、状態ベースのテストによって、2つのコードパスのどちらがたどられたかを判断できる場合があります。
2つのコードパスの結果の間に外部から観察できる違いがない場合は、この特定の実装の詳細をテストしない方がよいでしょう。過剰指定テストと呼ばれるアンチパターンにつながる可能性があります。このアンチパターンや他の多くの単体テスト関連の詳細については、優れた書籍xUnitTestPatternsを参照してください。
編集:
リポジトリのテストは同じ方法で行うことができます:
var myObjMock = new Mock<MyObj>();
myObjMock.Setup(m => m.IsNew).Returns(true);
var repositoryMock = new Mock<Repository>();
repositoryMock.Setup(m => m.Create(myObjMock.Object)).Verifiable();
var sut = new SomeClass(repositoryMock.Object);
sut.Save(myObjMock.Object);
repositoryMock.Verify();
検証可能への呼び出しが鍵です。これがない場合、Moqのデフォルトの動作は、邪魔にならないようにし、可能な限り最善を尽くし、可能な限り例外をスローしないことです。
検証可能と呼ぶとき、あなたはその特定の振る舞いを期待するようにモックに指示します。ベリファイを呼び出したときにその期待が満たされていない場合、例外がスローされるため、テストは失敗します。