2

私のクラスでは、デリゲートタイプを宣言し、そのインスタンスを作成してから、そのインスタンスからBeginInvokeを呼び出しています。

public class ClassA
{
    ...
    public delegate bool MyDelegate(int x);
    ...
    public void MethodA()
    {
        ...
        var myDelegate = new MyDelegate(Foo);
        myDelegate.BeginInvoke(...);
        ...
    }
    ...
}

MethodAの単体テストを作成する際に、 BeginInvokeが呼び出されることは実際には望んでいません。私がやりたいのは、Molesフレームワークを使用してBeginInvoke呼び出しを無効にすることです。普段はやってみます

MMyDelegate.AllInstances.BeginInvoke... = (...) => { /* something here */ }

しかし、MyDelegateタイプのモルを生成することはできませんでした。

http://msdn.microsoft.com/en-us/library/system.delegate.aspxによると、「共通言語ランタイムは、各デリゲートタイプにBeginInvokeメソッドとEndInvokeメソッドを提供します」。これが事実であり、BeginInvokeがDelegateクラス(CLRによって提供される)内のメソッドでさえない場合、それをモル化することさえ可能ですか?デリゲートタイプからBeginInvokeを削除することに運が良かった人は他にいますか?

4

1 に答える 1

2

Microsoft Molesについてはよくわかりませんが、Microsoft Fakesで同じことを実現しようとしました(実際、これはVisual Studio 2012PremiumおよびUltimateに組み込まれているMicrosoftMolesの継承者です)。

偽のアセンブリを作成しようとすると(MicrosoftがMolesとStubsではなくFakesとShimsと呼んでいることを知っています)、次の警告が表示されました。

Warning 1   Cannot generate stub for AssemblyUnderTest.FooDelegate: type is sealed. d:\Sources\Projects\PlayingWithMoles\PlayingWithMoles\Fakes\AssemblyUnderTest.fakes
Warning 2   Cannot generate shim for AssemblyUnderTest.FooDelegate: type is a delegate. d:\Sources\Projects\PlayingWithMoles\PlayingWithMoles\Fakes\AssemblyUnderTest.fakes

(この警告を受け取るには、偽の構成ファイルで追加の診断をオフにする必要があります(形式が偽とモールで同じかどうかはわかりません):

<Fakes xmlns="http://schemas.microsoft.com/fakes/2011/" **Diagnostic="true"**>
  <Assembly Name="AssemblyUnderTest"/>
</Fakes>

しかし、残念ながら、この警告は、これができないことを明確に示しています。ただし、別の非同期API、たとえばタスク並列ライブラリ(別名TPL )に移動することで、この問題を完全に回避できます。

Task(またはTask of T)オブジェクト自体は、非同期操作をファーストクラスオブジェクトとして表します。これにより、この「非同期操作」をフィールドに格納したり、メソッドから返したり、渡したりすることができます。これにより、偽の実装を簡単にモックできるため、テストの可能性が大幅に向上します。

class SomeService
{
  Task<string> GetSomeResult()
  {
    // Performing long-running operation to obtain the result
  }
}

class YourServiceConsumer
{
  private void YourMethod()
  {
     Task<string> task = service.GetSomeResult();
  }
}

別のインターフェイスを使用して依存関係を簡単に抽出し、YourServiceConsumerレイヤーを追加せずに、依存関係を挿入したり、Microsoft Moles(またはMicrosoft Fakes)を使用して偽造したりすることができます。

于 2012-11-29T20:58:23.120 に答える