使用Moq模拟Delegate.Invoke()会在LINQ中引发InvalidCastexception
假设我有IService
接口:
public interface IService { string Name { get; set; } }
以及返回此接口的委托Func
。
在我的unit testing中,我想使用Moq模拟委托的Invoke()
方法,如下所示:
[TestMethod] public void UnitTest() { var mockService = new Mock(); var mockDelegate = new Mock<Func>(); mockDelegate.Setup(x => x.Invoke()).Returns(mockService.Object); // The rest of the test }
不幸的是, mockDelegate.Setup(...)
抛出System.InvalidCastException
:
测试方法UnitTest抛出exception:
System.InvalidCastException:无法将类型为“System.Linq.Expressions.InstanceMethodCallExpressionN”的对象强制转换为“System.Linq.Expressions.InvocationExpression”。
在Moq.ExpressionExtensions.GetCallInfo(LambdaExpression表达式,模拟模拟)
在Moq.Mock。 c_ DisplayClass1c`2.b _1b()
在Moq.PexProtector.Invoke(Func`1函数)
在Moq.Mock.Setup(模拟
1 mock, Expression
1表达式,条件条件)在Moq.Mock
1.Setup(Expression
1表达式)在UnitTests.cs中的UnitTest():第38行
第38行是mockDelegate.Setup(x => x.Invoke()).Returns(mockService.Object);
我错过了什么吗? 或者模拟委托调用通常不是一个好主意?
谢谢。
在Moq中完成此操作是100%可行的,具体方法如下:
var mockService = new Mock(); var mockDelegate = new Mock>(); mockDelegate.Setup(x => x()).Returns(mockService.Object);
您获得InvalidCastException
的原因是因为您正在创建委托类型的Mock
。 因此,期望Expression
的类型为InvocationExpression
( x()
)而不是InstanceMethodCallExpressionN
( x.Invoke()
)。
这也允许您validationMock
委托的调用,例如
mockDelegate.Verify(x => x(), Times.Once);
我已将此作为答案发布,因为虽然对于这种情况可能没有必要,但知道肯定是有用的。
这个答案是对SLaks
和nemesv
评论的总结。
没有理由首先模拟Func
delegate
。 相反,人们可以写:
[TestMethod] public void UnitTest() { var mockService = new Mock(); Func mockDelegate = () => mockService.Object; // The rest of the test }
例外是因为Moq不支持这种情况。 但是,不是抛出NotSupportException
而是InvalidCastException
。