25

私は同期asp.netコードの本体を.net4.5と新しい非同期構文に変換することに取り組んでいます。

次のようなテストコードがたくさんあります。

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

DoSomethingの署名をからに変換するときはFoo DoSomething()async Task<Foo> DoSomething()すべてのテストコードを書き直す必要があります。私の現在の回避策は、元のコードを次のようなものに変換することです。

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

これは特に難しい変換ではありませんが、更新する必要のあるテストが何千もある場合は面倒です。

そのフォームmのいくつかを実行するためにReturnsAsyncと呼ばれる拡張メソッドを作成しようとしましたが、型推論の問題がいくつかあり、完全に特定することはできませんでした。この種のモックを変換して非同期メソッドをより適切に処理するための標準的またはより簡単な方法はありますか?

4

2 に答える 2

35

まず、名前付け: タスクベースの非同期パターン (TAP) では、非同期で s を返すすべてのメソッドは、 でTask終わる名前を付ける必要がありますAsync。したがって、メソッドの名前はDoSomethingAsync.

第二に、のコンストラクターは、開始されていないをTask作成します。手動で作成する必要があります。実際のメソッドもこれを行う場合、これも TAP に従わず、コードが でうまく機能しないことを意味します。代わりに、または、さらに良いのは、を使用する必要があります。TaskStart()DoSomethingawaitTask.Run(() => value)Task.FromResult(value)

第三に、うまく動かなかったコードを見せていただければ、どこで間違いを犯したかを教えていただけると助かります。

さて、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));
    }
}
于 2012-08-23T13:19:19.550 に答える
21

Moq 4.2 ではReturnsAsync()拡張メソッドが追加されたため、独自のメソッドを追加する必要はなくなりました。

于 2014-02-26T12:28:00.013 に答える