Luís Guilherme Luís Guilherme - 5 months ago 34
C# Question

Invoking Func passed as a parameter to a mock using Moq and C#

I have a mocked method that looks like this:

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

In my code, I do such as:

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;

My case is, I am testing MyMethod with Moq and I want to verify the Func behaviour is as expected. I have some injected objects in its body, that are mocks, and should be verified; it also starts building my return value, so I can't do any assertion unless I invoke the function passed as parameter.

In Java and jUnit + EasyMock , I would capture the parameter passed, like this:

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



How do I do the same using C# + Moq?


You can capture invocation argument when provide Returns for method:

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

Here is complete test for your code:

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

Also you need test for case when mockInjected1.Method returns false.