宣言するインターフェースがあります
Task DoSomethingAsync();
私は自分のテストにMoqFrameworkを使っています。
[TestMethod()]
public async Task MyAsyncTest()
{
Mock<ISomeInterface> mock = new Mock<ISomeInterface>();
mock.Setup(arg => arg.DoSomethingAsync()).Callback(() => { <my code here> });
...
}
それから私のテストで私はawait DoSomethingAsync()
を呼び出すコードを実行します。そしてテストはその行で失敗します。何がおかしいのですか?
あなたのメソッドはコールバックを持っていないので、.CallBack()
を使う理由はありません。 .Returns()
と Task.FromResult を使用して、単純にTaskを希望の値で返すことができます。
MyType someValue=...;
mock.Setup(arg=>arg.DoSomethingAsync())
.Returns(Task.FromResult(someValue));
更新2014-06-22
Moq 4.2には、これを支援するための2つの新しい拡張方法があります。
mock.Setup(arg=>arg.DoSomethingAsync())
.ReturnsAsync(someValue);
mock.Setup(arg=>arg.DoSomethingAsync())
.ThrowsAsync(new InvalidOperationException());
更新2016-05-05
Seth Flowersが その他の答え で述べているように、ReturnsAsync
はTask<T>
を返すメソッドに対してのみ利用可能です。 Taskだけを返すメソッドの場合、
.Returns(Task.FromResult(default(object)))
に使える。
この答え に示すように、.NET 4.6では、これは.Returns(Task.CompletedTask);
に簡略化されています。
mock.Setup(arg=>arg.DoSomethingAsync())
.Returns(Task.CompletedTask);
類似の問題
私は大体次のようなインタフェースを持っています。
Task DoSomething(int arg);
症状
テスト対象のサービスawaited
がDoSomething
への呼び出しを行ったときに私のユニットテストが失敗しました。
修
このシナリオでは、このメソッドの.ReturnsAsync()
でSetup()
を呼び出すことはできません。これは、このメソッドがTask<T>
ではなく非総称のTask
を返すためです。
しかし、あなたはまだセットアップに.Returns(Task.FromResult(default(object)))
を使うことができ、テストに合格することができます。
コールバックの後に.Returns(Task.FromResult(0));
を追加するだけです。
例:
mock.Setup(arg => arg.DoSomethingAsync())
.Callback(() => { <my code here> })
.Returns(Task.FromResult(0));
今、あなたはまたTalentsoft.Moq.SetupAsyncパッケージを使うことができます https://github.com/TalentSoft/Moq.SetupAsync
ここで見つかった回答とMoqに提案したアイデアはまだここにはまだ実装されていません。 https://github.com/moq/moq4/issues/384 、非同期メソッドの設定を大幅に簡素化します。
SetupAsync拡張機能を使用した以前の応答で見つかった例はほとんどありません。
mock.SetupAsync(arg=>arg.DoSomethingAsync());
mock.SetupAsync(arg=>arg.DoSomethingAsync()).Callback(() => { <my code here> });
mock.SetupAsync(arg=>arg.DoSomethingAsync()).Throws(new InvalidOperationException());