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