2012-08-22 14 views
25

同期asp.netコードの本体を.net 4.5と新しい非同期構文に変換する作業を進めています。私のテストコードのすべてを書き直さなければならないが、私はasync Task<Foo> DoSomething()Foo DoSomething()からのdoSomethingの署名を変換する場合同期Moqモックを非同期に変換

var retVal = new Foo(bar,baz); 
_myMock.Setup(x => x.DoSomething(123)).Returns(retVal); 

は、私は次のようになり、テストコードの多くを持っています。私の現在の回避策は次のように元のコードを変換するためにされています。これは特に、ハード変換が、私は更新する必要があるテストの数千を持っている場合、それは退屈ではない

var retVal = new Foo(bar,baz); 
_myMock.Setup(x => x.DoSomething(123)) 
    .Returns(new Task<Foo>(()=>retVal)); 

私は、ReturnAsyncという拡張メソッドを使ってそのフォームmのいくつかを実行しようとしましたが、私は決して釘付けできない型の推論の問題を抱えていました。この種のモックを非同期メソッドをよりうまく処理するように変換する標準的で簡単な方法はありますか?

答えて

20

部品番号4.2はReturnsAsync()拡張メソッドを追加していないので、あなたは、もはや自分自身を追加する必要があります。

34

最初に、タスクベースの非同期パターン(TAP)は、非同期であり、Taskを返すすべてのメソッドの名前の末尾をAsyncとする必要があります。したがって、方法はDoSomethingAsyncとする必要があります。

第2に、Taskのコンストラクタは、開始されていないTaskを作成します。Start()を手動で作成する必要があります。もしあなたの実際のDoSomethingメソッドもこれを行うなら、それは再びTAPに従わないので、あなたのコードはawaitとうまく動作しません。代わりに、Task.Run(() => value)、またはそれ以上の場合はTask.FromResult(value)を使用してください。

第3に、コードがうまくいかなかったことを示して、どこで間違いを犯したかを教えてもらえると良いでしょう。

ReturnsAsync()拡張メソッドの本体はかなりシンプルですが、私の仕事の大部分は正しいタイプを特定することでした(特に私はMoqを知らないので)。コードは次のようになります。

public static class MoqExtensions 
{ 
    public static IReturnsResult<TMock> ReturnsAsync<TMock, TResult>(
     this IReturns<TMock, Task<TResult>> setup, TResult value) 
     where TMock : class 
    { 
     return setup.Returns(Task.FromResult(value)); 
    } 
} 
関連する問題