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’.
what is _ => _ () on lines 11 and 12?
It’s a lambda used by Moq to set up or verify the function. In a lambda, the variable name can be anything that isn’t already in scope so the “_” could be anything, e.g. ( x => x.Whatever ). I use underscore by convention because I don’t actually care what that thing is or use any of its properties. The purpose of the line is to verify that the mock delegate was called with the specified parameters.
You saved my day