Let's say that I have IService
interface:
public interface IService
{
string Name { get; set; }
}
And a delegate Func<IService>
that returns this interface.
In my unit test I want to mock the delegate's Invoke()
method using Moq like this:
[TestMethod]
public void UnitTest()
{
var mockService = new Mock<IService>();
var mockDelegate = new Mock<Func<IService>>();
mockDelegate.Setup(x => x.Invoke()).Returns(mockService.Object);
// The rest of the test
}
Unfortunately mockDelegate.Setup(...)
throws System.InvalidCastException
:
Test method UnitTest threw exception:
System.InvalidCastException: Unable to cast object of type 'System.Linq.Expressions.InstanceMethodCallExpressionN' to type 'System.Linq.Expressions.InvocationExpression'.
at Moq.ExpressionExtensions.GetCallInfo(LambdaExpression expression, Mock mock)
at Moq.Mock.<>c_DisplayClass1c`2.b_1b()
at Moq.PexProtector.Invoke(Func`1 function)
at Moq.Mock.Setup(Mock
1 mock, Expression
1 expression, Condition condition)at Moq.Mock
1.Setup(Expression
1 expression)at UnitTest() in UnitTests.cs: line 38
Line 38 is mockDelegate.Setup(x => x.Invoke()).Returns(mockService.Object);
Am I missing something? Or mocking delegate invocation is generally not a good idea?
Thank you.
This answer is a summary of
SLaks
andnemesv
comments.There is no reason to mock
Func<IService>
delegate
in the first place. Instead one can write:The exception is there because because this scenario is not supported by Moq. But instead of throwing a
NotSupportException
you get not so niceInvalidCastException
.It is 100% possible to do this in Moq, here is how:
The reason you were getting the
InvalidCastException
was because you are creating aMock<T>
of a delegate type. Thus it is expecting theExpression
to be of typeInvocationExpression
(x()
) rather thanInstanceMethodCallExpressionN
(x.Invoke()
).This also allows you to verify invocations of your
Mock
delegate, e.g.I have posted this as an answer because while it may not be necessary for this situation, it can certainly be useful to know.