9

次のようなモックメソッドがあります。


class NotMineClass {
  T Execute(Func operation) 
  {
    // do something
    return operation();
  }
}

私のコードでは、次のようにします。


public MyType MyMethod()
{
  MyType object = new MyType();
  bool success = notMineClassInstance.Execute(() =>
  {
    // some things
    retVal = injectedObject1.method();
    object.attribute = injectedObject2.method();
    // some other things
    return retVal;
  }
  if (success) 
  {
    object.otherAttribute = someValue;
  }
  return object;
}

私の場合、MyMethod を Moq でテストしており、Func の動作が期待どおりであることを確認したいと考えています。私はその本体にいくつかの注入されたオブジェクトを持っています。これはモックであり、検証する必要があります。また、戻り値の作成も開始されるため、パラメーターとして渡された関数を呼び出さない限り、アサーションを行うことはできません。

Java と jUnit + EasyMock では、渡されたパラメーターを次のようにキャプチャします。


public void testMyMethod() {
  // ...
  Capture < Function < void, Boolean > > functionCapture = Captures.last();
  expect(notMineClassInstance.execute(EasyMock.capture(functionCapture)));
  // Expectations for the body of the function

  replay();

  functionCapture.getValue().apply(null);
}

C# + Moq を使用して同じことを行うにはどうすればよいですか?

4

1 に答える 1

16

Returnsメソッドを提供するときに、呼び出し引数をキャプチャできます。

Mock<NotMineClassInstance> mock = new Mock<NotMineClassInstance>();
mock.Setup(x => x.Execute<bool>(It.IsAny<Func<bool>>()))
    .Returns((Func<bool> captured) => { captured(); return true; });

コードの完全なテストは次のとおりです。

[Test]
public void TestingSomething()
{
    // Arrange
    Mock<NotMineClassInstance> mockNotMine = new Mock<NotMineClassInstance>();
    mockDep.Setup(x => x.Execute<bool>(It.IsAny<Func<bool>>())).Returns((Func<bool> func) => func());

    Mock<Injected1> mockInjected1 = new Mock<Injected1>();
    mockInjected1.Setup(i => i.Method()).Returns(true);

    Mock<Injected2> mockInjected2 = new Mock<Injected2>();
    mockInjected2.Setup(i => i.Method()).Returns("xxx");

    YourClass yourObject = new YourClass(mockDep.Object, mockInjected1.Object, mockInjected2.Object);

    // Act
    MyType my = yourObject.MyMethod();    

    // Assert
    mockNotMine.Verify(d => d.Execute<bool>(It.IsAny<Func<bool>>()));
    mockInjected1.Verify(i => i.Method());
    mockInjected2.Verify(i => i.Method());

    Assert.That(my.Attribute, Is.EqualTo("xxx"));
    Assert.That(my.OtherAttribute, Is.EqualTo(someValue));            
}

また、mockInjected1.Method が false を返す場合のテストも必要です。

于 2012-04-18T19:37:26.517 に答える