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