2013-02-05 3 views
37

私はWinRTのアプリのためのユニットテストを書いている、と私はこれを使用して、非非同期プライベートメソッドを呼び出すことができています:しかしWinRTでリフレクトを使用して呼び出される非同期のプライベートメソッドを待つ方法

TheObjectClass theObject = new TheObjectClass(); 
Type objType = typeof(TheObjectClass); 
objType.GetTypeInfo() 
     .GetDeclaredMethod("ThePrivateMethod") 
     .Invoke(theObject, null); 

を、問題のプライベートメソッドがasyncであれば、コードが実行を継続しますそれが終わるのを待たずに。

これにawaitの機能を追加するにはどうすればよいですか?

+0

これはWinRTアプリケーションなので、プライベートメンバーの反映/呼び出しが許可されていないと感じています。私はこれについてGoogleの正式な文書を見つけることができません、最も近いです:http://blogs.microsoft.co.il/blogs/sasha/archive/2011/09/17/metro-net-framework-profile-windows -tailored.aspx編集:これは単体テストなので多分問題ではありません。 :) –

+0

@Chris Sinclair実際、私が上に持っているコードは、プライベートメソッドのために完璧に動作します。私の問題は、特に非同期の問題です。この問題は、リフレクションによって呼び出されるパブリックメソッドにも適用されます。 – jokeefe

答えて

69

このメソッドで返された値を使用する必要があります。あなたはそのタイプを知っていますか?それは常にTaskだ場合たとえば、あなたが使用できます。

await (dynamic) objType.GetTypeInfo() 
         .GetDeclaredMethod("ThePrivateMethod") 
         .Invoke(theObject, null); 

I:

await (Task) objType.GetTypeInfo() 
        .GetDeclaredMethod("ThePrivateMethod") 
        .Invoke(theObject, null); 

あなたはそれがawaitableなり、戻り値の型を知っているがわからない場合は、動的型付けを使用することができますを試してみてください。最初のユニットテストでは、リフレクションによってプライベートメソッドを呼び出す必要はありません。パブリック(または内部)APIを介して間接的にテストできますか?それは一般的に望ましいことです。

+0

しかし、GetAwaiter()が拡張メソッドである場合、 'dynamic'へのキャストは機能しません。これは、WinRTの' IAsyncAction'の場合とまったく同じです。 – svick

+0

@Jon Skeet:ありがとう!これはそれでした。 'Task'オブジェクトが返されたので、私がする必要があったのはそれをキャストして' await'を追加することでした。また、ユニットテストメソッドの戻り型 'Task'を' async'にしたり、ユニットテストフレームワークで実行しないようにする必要があることも発見しました。 – jokeefe

+0

@Jeff:コンパイラのエラーのような詳細を伝えると助かります。それについてのコメントの議論をするのではなく、新しい質問を作成する価値があるかもしれません。 –

6

Invokeは、Taskに変換可能なオブジェクトを返す必要があります。ちょうどawaitです。

プライベートメソッドがvoidを返す場合は、カスタムSynchronizationContextが必要です。これは面倒です。あなたのメソッドがTask/Task<T>を返す方が良いです。