Mocking Delegate.Invoke()使用Moq throws LINQ中的InvalidCast异常 [英] Mocking Delegate.Invoke() using Moq throws InvalidCast exception in LINQ

查看:285
本文介绍了Mocking Delegate.Invoke()使用Moq throws LINQ中的InvalidCast异常的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

让我们说我有 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(Mock 1 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(Mock1 mock, Expression1 expression, Condition condition)

at Moq.Mock1.Setup(Expression1 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆