2011-11-29 8 views
1

モルズを使用してIsHappy機能をテストするにはどうすればよいですか?Molesを使って仮想メソッドをテストするには?

class SomeClass 
{ 
    protected virtual bool IsHappy(string mood) 
    { 
      return (mood == "Happy"); 
    } 
} 

Iは、スタブを使用してかどうかをテストすることを試みた:

SSomeClass stub = new SSomeClass(); 
stub.CallBase = true; 
Assert.IsTrue(stub.IsHappyString("Happy")); 

を...しかしIsHappyString方法は、このようにNullReference例外をスローnullを返します。

IsHappyメソッドのデフォルト実装をテストするにはどうすればよいですか?

答えて

1

スタブとモルズは、環境依存性またはクラス依存性のいずれかの依存性からクラスを分離するためのものです。このクラスは何の依存関係も持っていないので、なぜあなたはそれを偽造しようとしていますか?

人がそれを上書きするときにこの基本クラスが正しく機能するようにしたい場合は、テスト実装を作成する必要があります。その場合、これはあなたのテストケースがどのように見えるか、多かれ少なかれです。

public SomeClassTestAdapter : SomeClass 
{ 
    public bool GetIsHappy(string mood) 
    { 
     return IsHappy(mood); 
    } 
} 

[Test] 
public void ShouldReturnTrueWhenPassedHappy() 
{ 
    var classUnderTest = new SomeClassTestAdapter(); 
    bool result = classUnderTest.IsHappy("Happy"); 
    Assert.IsTrue(result, "Expected result to be true"); 
} 

[Test] 
public void ShouldReturnFalseWhenPassedLowerCaseHappy() 
{ 
    var classUnderTest = new SomeClassTestAdapter(); 
    bool result = classUnderTest.IsHappy("happy"); 
    Assert.IsFalse(result, "Expected result to be false"); 
} 

[Test] 
public void ShouldReturnFalseWhenPassedNull() 
{ 
    var classUnderTest = new SomeClassTestAdapter(); 
    bool result = classUnderTest.IsHappy(null); 
    Assert.IsFalse(result, "Expected result to be false"); 
} 

スタブまたはモルで圧迫されなければならない、このコードには場所がありません

の場合このケースのためのアダプタクラスを作成したくない場合は、Molesのような大きな有料の依存関係ではなく、組み込みの.Net機能を使用できます。リフレクションとダイナミックで保護されたメンバーやプライベートメンバーにアクセスできます。この例を参照してください:

+0

IsHappyメソッドは 'protected'です。クラスアンダーテストからメソッドを直接呼び出してアクセスすることはできません。 – Ian

+0

@イアン:申し訳ありませんが、これに戻るにはとても時間がかかりました。私の回答が更新されました –

2

私はここにスタブを忘れると思います。スタブ/モックは、依存関係の動作を偽装したいときに使用します。この例では

public class Foo 
    { 
     public virtual int GetFoosInt() 
     { 
      return 12; 
     } 
    } 
    public class FooClient 
    { 
     private Foo _foo; 

     public FooClient(Foo foo) 
     { 
      _foo = foo; 
     } 

     public int AddOneToFoosInt() 
     { 
      return _foo.GetFoosInt() + 1; 
     } 
    } 

FooClientをテストするとき、何をテストすること)それは(GetFoosInt」より1を返すことである:あなたがテストしたいと、それは工assを使用SomeClassClientを持っていた場合、あなたの工assスタブと思います" FooClientをテストするためにFoosIntが何であるかは実際は気にしません。したがって、Fooスタブを作成してGetFoosIntを設定して、必要なものを返すことができます。あなたのケースでは

、保護された仮想メンバーをテストし、私はこれでいいと思う:これはあなたに保護された仮想テストするデフォルトの動作への「直接のアクセスを提供します

[TestClass] 
public class SomeClassTest 
{ 
    private class DummySomeClass : SomeClass 
    { 
     public bool IsHappyWrapper(string mood) 
     { 
      return IsHappy(mood); 
     } 
    } 

    [TestMethod] 
    public void SomeTest() 
    { 
     var myClass = new DummySomeClass(); 

     Assert.IsTrue(myClass.IsHappyWrapper("Happy")); 
    } 
} 

。注意を要するのは、抽象メンバの定義を開始して一般的なSomeClassに追加する場合、それらをこのダミー継承者に追加して、メンテナンスのオーバーヘッドを追加する必要があるということだけです。

私の主人公は、保護されたメンバーだけを残して、公開インターフェースを介してそれらをテストする必要があると言います。しかし、それはあなたの状況では実用的でないかもしれませんが、私はこのアプローチで実際には何の害も見ません。

+0

Moles.NETにこれを「自動化」する機能がありますか?モールにいくつかの行動コントロールがあります(Fallthroughなど)。ダミークラスを手動で作成する代用として使用できますか? – Ian

+0

私は分かりません。私はMolesを主にサードパーティの静的メソッド、ファイル、GUIなどの外部依存関係を模倣するために使用しました。私は一般的なモッキングエンジンとしてそれを使用していませんでした。代わりにMoqを使用することを選択しました。モルズはかなり強力ですので、これが可能であれば私には驚かないでしょうが、残念ながらトップがどのようになっているのか分かりません。 –

+0

以前、MSTestは保護された/非公開のメンバーを公開する特別なアセンブリである「アクセサ」を生成することができました。残念ながら、その機能のサポートを取りやめたようです(ただし、私がどこでそれを読んだかはわかりませんが)。 –

関連する問題