Dogs Chasing Squirrels

A software development blog

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’.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

w

Connecting to %s

%d bloggers like this: