2013-04-04 1 views
5

私は次のようにクラスを設定している:Microsoft Fakeは、シム上の抽象メソッドをサポートしていますか?

public abstract FooClass { 
    public FooClass() { 
     // init stuff; 
    } 

    public void RandomMethod() { 
     // do stuff; 
    } 

    public abstract WhatIWantToShim(); 
} 

は私がやりたいことはそうのようなShimFooClassにWhatIWantToShimに設定されている:

ShimFooClass.AllInstances.WhatIWantToShim =() => Boo(); 

私は、うまく

をRandomMethodを設定することができます
ShimFooClass.AllInstances.RandomMethod =() => CalculatePi(); 

ただし、生成されたShimFooClassは、ShimFooClassのAllInstancesプロパティにWhatIWantToShimプロパティを作成しないように見えます。

私はhttp://msdn.microsoft.com/en-us/library/hh549176.aspx#bkmk_shim_basicsを見ましたが、抽象メソッドについては何も表示されていません。私が参照しているのはサポートされていないファイナライザだけです。誰もがここで何が起こっているのか、このシナリオがサポートされているのか知っていますか?

+0

プロパティを設定するメソッドを作成できますか? – RedJandal

+0

あなたの後ろには、shimクラスで作成された抽象メソッドのプロパティはありません。それが問題だ。 –

答えて

4

ああ....

インターフェイスと抽象メソッドをがっかり。スタブは、テストで使用できるインタフェースと抽象メソッドの実装を提供します。 Shimsはメソッド本体を持たないため、インタフェースと抽象メソッドを実装することはできません。

http://msdn.microsoft.com/en-us/library/hh549175(v=vs.110).aspx

更新:シムをスタブですが、何ができるのか。

using (ShimsContext.Create()) 
{ 
    bool wasAbstractMethodCalled = false; 
    var targetStub = new StubFooClass() 
    { 
     WhatIWantToShim01 =() => wasAbstractMethodCalled = true 
    }; 
    var targetShim = new ShimFooClass(targetStub); 
    targetShim.AllInstances.RandomMethod =() => CalculatePi(); 
    FooClass target = targetShim.Instance; 
    target.WhatIWantToShim(); 
    Assert.IsTrue(wasAbstractMethodCalled, "The WhatIWantToShim method was not called."); 
} 

シムはWhatIWantToShim方法とスタブを迂回処理できないので、ちょうどスタブクラスの新しいインスタンスを作成し、抽象メソッドのための迂回ハンドラを設定することができます。 (注:私の実際のコードでFakeが生成されたときにWhatIWantToShimの最後にタグ付けされた01が自動的に追加されました)。

次に、インスタンス化されたスタブをshimクラスのコンストラクタに渡し、必要に応じてシムを外します。

0

他の回答が質問に答えることができず、今後の検索で有用な情報が返されると確信しているので、ここで返信します。

まず、シムインターフェイスは使用できません。抽象メソッドはインタフェースと同等です。さらに、理由はありません。

{ 
    bool wasAbstractMethodCalled = false; 
    var targetStub = new StubFooClass() 
    { 
     WhatIWantToShim01 =() => wasAbstractMethodCalled = true 
    }; 
    ShimFooClass.AllInstances.RandomMethod = @class => targetStub.CalculatePi(); 
    targetStub.WhatIWantToShim(); 
    Assert.IsTrue(wasAbstractMethodCalled, "The WhatIWantToShim method was not called."); 
} 

上記は以前の回答の簡略化されたバージョンで、単に割り当てたアクションを呼び出します。これはおそらくあなたの意図ではありません。

なぜあなたはシムですか?あなたがテストしているメソッドの中でメソッド呼び出しの影響を避けたいときは、シムです。抽象メソッドはボディを持たないため、何にも影響を与えません。これが有用な唯一の時間は、シムが最初に利用できるチャイルドクラスです。

問題が発生する可能性がある唯一の状況は、第3のクラスが、抽象クラスのインスタンスを密かに保持し、それを子クラスでインスタンス化する場合です。あなたはそれを偽造することはできません。しかし、それはひどいデザインです。インスタンスは、(シム)またはいくつかのメソッドから来ている必要があります(DIは良いことだから!)抽象化は無駄です。抽象化を何も使用していないので、インスタンスを子型として宣言することもできます。

関連する問題