假设我有IService
接口:
public interface IService
{
string Name { get; set; }
}
和一个返回此接口的委托Func<IService>
。
在我的单位测试中,我想使用以下索款嘲笑代表的Invoke()
方法:
[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
}
不幸的是mockDelegate.Setup(...)
抛出System.InvalidCastException
:
测试方法 Unittest抛出例外:
system.invalidcastException:无法施放类型的对象'system.linq.expressions.instancemethodcallexpressionn'to 键入'System.Linq.expressions.invocation Expression'。
在moq..expressextensions.getCallinfo(lambdaexpression表达式,模拟模拟)
在MOQ.Mock。
在moq.pexprotector.invoke(func`1函数)
在moq.mock.setup(模拟
1 mock, Expression
1表达,条件条件)在MOQ.Mock
1.Setup(Expression
1表达式)in UnitSests.cs in UnitTest():38行
第38行是mockDelegate.Setup(x => x.Invoke()).Returns(mockService.Object);
我想念什么吗?或嘲笑委托召唤通常不是一个好主意?
谢谢。
可以在订阅中100%这样做,这是:
var mockService = new Mock<IService>();
var mockDelegate = new Mock<Func<IService>>();
mockDelegate.Setup(x => x()).Returns(mockService.Object);
您获得InvalidCastException
的原因是因为您正在创建委托类型的Mock<T>
。因此,它预计Expression
为InvocationExpression
类型(x()
),而不是InstanceMethodCallExpressionN
(x.Invoke()
)。
这还允许您验证Mock
委托的调用,例如
mockDelegate.Verify(x => x(), Times.Once);
我已经将其发布为答案,因为虽然对于这种情况可能不是必需的,但知道它肯定很有用。
此答案是SLaks
和nemesv
注释的摘要。
首先没有理由模拟Func<IService>
delegate
。相反,一个人可以写:
[TestMethod]
public void UnitTest()
{
var mockService = new Mock<IService>();
Func<IService> mockDelegate = () => mockService.Object;
// The rest of the test
}
有例外情况,因为该方案不受签名的支持。但是,而不是抛出NotSupportException
,而不是那么好InvalidCastException
。