Dogs Chasing Squirrels

A software development blog

Monthly Archives: May 2018

Mocking delegates with Moq

0

Using Delegates

In C#, a delegate is a function signature that can be passed around as a parameter. This is a delegate that takes a couple of parameters and returns a value:

public delegate int DoSomething( double x, string y );

This is a method that puts it to work with Invoke:

    public int CallDelegate( DoSomething doSomething, double x, string y ) {
        return doSomething?.Invoke( x, y ) ?? 0;
    }

You don’t need to use Invoke, you can use it directly via:

        return doSomething( x, y );

but Invoke is nice because you can guard against nullables.

Mocking Delegates

When unit testing with Moq, you may find yourself wanting to mock a delegate or to verify that it was called. It’s straightforward, just make sure you mock the method itself and not Invoke:

        [TestMethod]
        public void TestMethod() {

            var mockDoSomething = new Mock<MyClass.DoSomething>();
            mockDoSomething.Setup( _ => _( It.IsAny<double>(), It.IsAny<string>() ) ).Returns( 5 );
            // NOT
            // mockDoSomething.Setup( _ => _.Invoke( It.IsAny<double>(), It.IsAny<string>() ) ).Returns( 5 );
            var subject = new MyClass();
            var result = subject.CallDelegate( mockDoSomething.Object, 1.1, "x" );
            Assert.AreEqual( 5, result );
            mockDoSomething.Verify( _ => _( 1.1, "x" ), Times.Once );
            mockDoSomething.Verify( _ => _.Invoke( 1.1, "x" ), Times.Once );            
        }
    }

If you try to mock Invoke itself, you’ll get an error like:

System.InvalidCastException: Unable to cast object of type ‘System.Linq.Expressions.InstanceMethodCallExpressionN’ to type ‘System.Linq.Expressions.InvocationExpression’.