2011-10-21 15 views
7

保護されたヘルパーを呼び出すコードをテストするためにMOQを使用する方法次:は次のようになり、私は現在、テストを実行

// In Blah.cs 
public class ClassUnderTest 

{ 

    public bool MethodUnderTest() 

    { 

     // Do a bunch of stuff... 

     return HelperMethod(); 

    } 



    protected virtual bool HelperMethod() 

    { 

     bool success = false; 

     // Proprietary Hardware Access. 

     // Database Calls. 

     // File System Modifications. 

     return success; 

    } 

} 


// In TestBlah.cs 

public class TestStub : ClassUnderTest 

{ 

    public bool HelperMethodReturnValue; 



    protected override bool HelperMethod() 

    { 

     return HelperMethodReturnValue; 

    } 

} 



[TestClass] 

public class TestingClass 

{ 

    [TestMethod] 

    public void ClassUnderTest_MethodUnderTest_TestHelperReturnsTrue() 

    { 

     var stub = new TestStub(); 

     stub.HelperMethodReturnValue = true; 

     Assert.IsTrue(stub.MethodUnderTest()); 

    } 



    [TestMethod] 

    public void ClassUnderTest_MethodUnderTest_TestHelperReturnsFalse() 

    { 

     var stub = new TestStub(); 

     stub.HelperMethodReturnValue = false; 

     Assert.IsFalse(stub.MethodUnderTest()); 

    } 

} 

上記の単純なもののために正常に見えるが、しかし、スタブクラスはすぐに指数関数的に大きく、より複雑になります。 私はMoqを使ってスタブクラスを置き換えたいと思います。しかし、何らかの理由で保護されたメソッドに戻り値を設定できないため、これはコンパイルされません。

[TestMethod] 

public void ClassUnderTest_MethodUnderTest_TestHelperReturnsFalse() 

{ 

    var mockClass = new Mock<ClassUnderTest>(); 
    mockClass.Protected().Setup("HelperMethod").Returns(false); 

    Assert.IsFalse(mockClass.Object.MethodUnderTest()); 

} 

これを行う方法については誰でも知っていますか? moqでこれを行うことはできますか?

+5

何かがここにないように思われます...あなたはあなたのSUTを嘲笑せず、あなたはその依存関係を模倣します。 –

+0

ええ、実際にYojinはSUTの一部を置き換えて保護されたヘルパーメソッドではなく、別々に保つ必要があります。 – Matthias

答えて

23

moq source code私はと思っています。は、ジェネリックバージョンのセットアップを明示的に呼び出す必要があります。ジェネリックでないバージョンはvoidメソッドに使われているようです。だから試してみてください

mockClass.Protected().Setup<bool>("HelperMethod").Returns(false); 

さらに、私はあなたのクラスデザインを再考することをお勧めします。 HelperMethod()がそのような束をしている場合、ClassUnderTestへの依存として注入される独自のクラスの価値があります。モックオブジェクトを使って実際に何かをテストするのではなく、モックオブジェクトをテストすることは、少なくともモックフレームワークのためのものではありません。

4

保護されたメソッドは依存関係を分離するための優れた方法ではありませんが、時には、特にテスト容易化のためにレガシーコードを適合させる場合に起こります。厄介な文字列ベースのMoq構文を避ける1つの方法は、メソッドを 'protected internal'(または他のアセンブリから通常の使用法でオーバーライドするつもりがない場合は単に 'internal')にすることです。次に、アセンブリでInternalsVisibleToを使用しますメソッドを公開する。これはちょっとしたハックですが、この目的のために保護されたメソッドを使用することは、すでに少しハックです。いくつかの点では、私は「内部」アプローチを好んでいます。これは、これがバックドアの方法であることを明確にしているため(通常の場合には上書きすると思われる保護された方法とは対照的に)使用法。

関連する問題