使用Moq和C调用作为参数传递给mock的Func#

使用Moq和C调用作为参数传递给mock的Func#,c#,.net,moq,capture,xunit,C#,.net,Moq,Capture,Xunit,我有一个模拟的方法,如下所示: class NotMineClass { T Execute(Func operation) { // do something return operation(); } } public void testMyMethod() { // ... Capture < Function < void, Boolean > > functionCapture = Captures.last();

我有一个模拟的方法,如下所示:


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

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);
}
在我的代码中,我执行以下操作:


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;
}
我的情况是,我正在用Moq测试我的方法,我想验证Func的行为是否符合预期。我在它的身体里有一些注射的物体,它们是模拟的,应该被验证;它还开始构建我的返回值,因此除非调用作为参数传递的函数,否则我无法执行任何断言

在Java和jUnit+EasyMock中,我将捕获传递的参数,如下所示:


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

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);
}

公共void testMyMethod(){
// ...
Capture>functionCapture=Captures.last();
expect(notMineClassInstance.execute(EasyMock.capture(functionCapture));
//对职能机构的期望
重播();
functionCapture.getValue().apply(空);
}

如何使用C#+Moq执行相同操作?

当为方法返回
时,您可以捕获调用参数:

Mock<NotMineClassInstance> mock = new Mock<NotMineClassInstance>();
mock.Setup(x => x.Execute<bool>(It.IsAny<Func<bool>>()))
    .Returns((Func<bool> captured) => { captured(); return true; });
Mock Mock=new Mock();
mock.Setup(x=>x.Execute(It.IsAny()))
.Returns((Func 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));            
}
[测试]
公开无效测试某物
{
//安排
Mock mockNotMine=新Mock();
mockDep.Setup(x=>x.Execute(It.IsAny())。返回((Func Func)=>Func());
Mock mockInjected1=新Mock();
mockInjected1.Setup(i=>i.Method())。返回(true);
Mock mockInjected2=新Mock();
mockInjected2.Setup(i=>i.Method())。返回(“xxx”);
YourClass yourObject=新建YourClass(mockDep.Object、mockInjected1.Object、mockInjected2.Object);
//表演
MyType my=yourObject.MyMethod();
//断言
验证(d=>d.Execute(It.IsAny());
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时,您还需要测试case。

看起来不错,但当我执行此操作时,会出现以下错误:test'failed:System.NullReferenceException:Object reference未设置为对象的实例。在Test.b_uu0(Func`1已捕获)@LuísGuilherme看到完整的测试样本时,它从一开始就工作了。我在Func调用中得到一个空引用:)