web-dev-qa-db-ja.com

moqを使用して一部のメソッドのみをモックする

次の方法があります。

public CustomObect MyMethod()
{
    var lUser = GetCurrentUser();
    if (lUser.HaveAccess)
    {
        //One behavior
    }
    else 
    {
        //Other behavior
    }

    //return CustomObject
}

私はモックしたいIMyInterface.GetCurrentUser。したがって、MyMethodを呼び出している間に、コードパスの1つにアクセスして確認できます。 Moqでそれを行う方法は?

私は次のことをしています:

var moq = new Mock<IMyInterface>();            
moq.Setup(x => x.GetCurrentUser()).Returns(lUnauthorizedUser);

//act
var lResult = moq.Object.MyMethod();

しかし、何らかの理由でlResultは常にnullであり、デバッグでMyMethodに入ろうとすると、常に次のステートメントにスキップします。

58

これは部分モックと呼ばれ、moqで行う方法としては、インターフェイスではなくクラスをモックし、モックされたオブジェクトの「Callbase」プロパティを「true」に設定する必要があります。

これには、テストするクラスのすべてのメソッドとプロパティを仮想化する必要があります。これが問題ではないと仮定すると、次のようなテストを作成できます。

 var mock = new Mock<YourTestClass>();
 mock.CallBase = true;
 mock.Setup(x => x.GetCurrentUser()).Returns(lUnauthorizedUser);
 mockedTest.Object.MyMethod();
119
lee

lee's answer の展開

クラスのすべてのメソッドとプロパティを仮想化する必要はなく、モックしたいものだけを作成します。

また、クラスの具体的な実装をモックする必要があることに注意してください。

var mock = new Mock<YourTestClass>(); // vs. var mock = new Mock<IYourTestInterface>();

クラスにデフォルトコンストラクターがない場合は、次の方法でクラスに渡す引数も指定する必要があります。

var mock = new Mock<YourTestClass>(x, y, z);
// or
var mock = new Mock<YourTestClass>(MockBehavior.Default, x, y, z);

x, y, zは、それぞれコンストラクターの1番目、2番目、3番目のパラメーターです。

最後に、モックを作成しようとしているメソッドが保護されている場合は、Moq.Protectedを含める必要があります

using Moq.Protected;

TReturnType returnValue = default(TReturnType);

mock.Protected()
    .Setup<TReturnType>("YourMockMethodName", It.IsAny<int>()) // methodname followed by arguments
    .Returns(returnValue);
22
Charles W

同様のケースがありました。次のコードは、モックされたメソッドと、インターフェイスの特定の実装からの実際のメソッドの両方を使用する柔軟性を与えてくれました。

var mock = new Mock<ITestClass>(); // Create Mock of interface

// Create instance of ITestClass implementation you want to use
var inst = new ActualTestClass();

// Setup to call method of an actual instance
// if method returns void use mock.Setup(...).Callback(...)
mock.Setup(m => m.SomeMethod(It.IsAny<int>())
    .Returns((int x) => inst.SomeMethod(x));

これで実際のメソッドを使用できますが、Verifyなどのメソッドを使用して、呼び出された回数を確認することもできます。

16
Brandon Rader