Mocking Delegate.Invoke()使用Moq throws LINQ中的InvalidCast异常 [英] Mocking Delegate.Invoke() using Moq throws InvalidCast exception in LINQ
问题描述
IService
接口: public interface IService
{
string Name {get;组; }
}
代理 Func< IService>
返回此界面。
在我的单元测试中,我想模拟代理的 Invoke()
使用Moq的方法如下:
[TestMethod]
public void UnitTest()
{
var mockService = new Mock< IService>();
var mockDelegate = new Mock< Func< IService>>();
mockDelegate.Setup(x => x.Invoke())。Returns(mockService.Object);
//其余的测试
}
不幸的是 mockDelegate.Setup(...)
throws System.InvalidCastException
:
测试方法
UnitTest抛出异常:
System.InvalidCastException:无法转换类型为System.Linq的对象.Expressions.InstanceMethodCallExpressionN'到
键入'System.Linq.Expressions.InvocationExpression'。
在Moq.ExpressionExtensions.GetCallInfo(LambdaExpression表达式,Mock mock)
在Moq.Mock。<> c_ DisplayClass1c`2.b _1b()
在Moq.Mock.Setup(Mock1 mock,Expression )中的Moq.PexProtector.Invoke(Func`1函数)
code> 1表达式,条件条件)
在Moq.Mock
1.Setup(表达式
1表达式)UnitTests.cs中的UnitTest()中的
第38行
第38行是 mockDelegate.Setup(x => x.Invoke())。Returns(mockService.Object);
我错过了什么?或者嘲笑委托调用一般不是一个好主意?
谢谢。
在Moq中可以做到这一点是100%的,这里是如何:
var mockService = new Mock< IService> ;();
var mockDelegate = new Mock< Func< IService>>();
mockDelegate.Setup(x => x())。Returns(mockService.Object);
您获得 InvalidCastException
的原因是因为您正在创建代理类型的 Mock< T>
。因此,它期待表达式
为类型 InvocationExpression
( x()
)而不是 InstanceMethodCallExpressionN
( x.Invoke()
)。
这也允许您验证您的 Mock
委托的调用,例如
mockDelegate.Verify(x => x(),Times.Once);
我已经发布了这个答案,因为在这种情况下可能没有必要有用的知道。
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.
It is 100% possible to do this in Moq, here is how:
var mockService = new Mock<IService>();
var mockDelegate = new Mock<Func<IService>>();
mockDelegate.Setup(x => x()).Returns(mockService.Object);
The reason you were getting the InvalidCastException
was because you are creating a Mock<T>
of a delegate type. Thus it is expecting the Expression
to be of type InvocationExpression
(x()
) rather than InstanceMethodCallExpressionN
(x.Invoke()
).
This also allows you to verify invocations of your Mock
delegate, e.g.
mockDelegate.Verify(x => x(), Times.Once);
I have posted this as an answer because while it may not be necessary for this situation, it can certainly be useful to know.
这篇关于Mocking Delegate.Invoke()使用Moq throws LINQ中的InvalidCast异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!