xUnitテストにasyncおよびawaitキーワードを適用する方法を見つけようとしています。xUnit1.9とAsyncCTP1.3を使用しています。これが私のテストケースです
1つの非同期メソッド呼び出しを指定するインターフェイスがあります
public interface IDoStuffAsync
{
Task AnAsyncMethod(string value);
}
インターフェイスを使用してasyncメソッドを呼び出すクラスがあります
public class UseAnAsyncThing
{
private readonly IDoStuffAsync _doStuffAsync;
public UseAnAsyncThing(IDoStuffAsync doStuffAsync)
{
_doStuffAsync = doStuffAsync;
}
public async Task DoThatAsyncOperation(string theValue)
{
await _doStuffAsync.AnAsyncMethod(theValue);
}
}
私のテストでは、メソッドDoThatAsyncOperation
が正しい値でメソッドを呼び出していることを確認したいので、インターフェイスをモックし、Moqを使用して呼び出しを確認します
[Fact]
public async void The_test_will_pass_even_though_it_should_fail()
{
var mock = new Mock<IDoStuffAsync>();
var sut = new UseAnAsyncThing(mock.Object);
mock.Setup(x => x.AnAsyncMethod(It.IsAny<string>()));
await sut.DoThatAsyncOperation("test");
// This won't throw a Moq.MockExcpetion so the test appears to pass
// However it does not run
mock.Verify(x => x.AnAsyncMethod("fail"));
}
このテストでは、async
andawait
キーワードを使用しています。Moqは検証が失敗したと主張する必要があるため、実行すると誤って合格します。の呼び出し後のコードsut.DoThatAsyncOperation("test");
は実行されません
[Fact]
public void This_will_work_and_assert_the_reslt()
{
var mock = new Mock<IDoStuffAsync>();
var sut = new UseAnAsyncThing(mock.Object);
mock.Setup(x => x.AnAsyncMethod(It.IsAny<string>()));
sut.DoThatAsyncOperation("test").ContinueWith(y => { });
// This won't throw a Moq.MockExcpetion so the test appears to pass
// However it does not run
mock.Verify(x => x.AnAsyncMethod("fail"));
}
このテストは、awaitキーワードとasyncキーワードなしでセットアップされ、正常に合格します。
これはxUnitとMoqで期待される動作ですか?
アップデート
スティーブンのコメントに感謝します。2つの変更を加えることで最初のテストを修正することができました。テストはvoidではなくタスクを返すようになり、モックもタスクを返します。
[Fact]
public async Task The_test_will_pass_even_though_it_should_fail()
{
var mock = new Mock<IDoStuffAsync>();
var sut = new UseAnAsyncThing(mock.Object);
mock.Setup(x => x.AnAsyncMethod(It.IsAny<string>())).ReturnAsync(true);
await sut.DoThatAsyncOperation("test");
// This now fails as it should
mock.Verify(x => x.AnAsyncMethod("fail"));
}