簡體   English   中英

使用Moq模擬Delegate.Invoke()會在LINQ中拋出InvalidCast異常

[英]Mocking Delegate.Invoke() using Moq throws InvalidCast exception in LINQ

假設我有IService接口:

public interface IService
{
    string Name { get; set; }
}

以及返回此接口的委托Func<IService>

在我的單元測試中,我想使用Moq模擬委托的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”的對象強制轉換為“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<IService>();

var mockDelegate = new Mock<Func<IService>>();
mockDelegate.Setup(x => x()).Returns(mockService.Object);

您獲得InvalidCastException的原因是因為您正在創建委托類型的Mock<T> 因此,期望Expression的類型為InvocationExpressionx() )而不是InstanceMethodCallExpressionNx.Invoke() )。

這也允許您驗證Mock委托的調用,例如

mockDelegate.Verify(x => x(), Times.Once);

我已將此作為答案發布,因為雖然對於這種情況可能沒有必要,但知道它肯定是有用的。

這個答案是對SLaksnemesv評論的總結。

沒有理由首先模擬Func<IService> delegate 相反,人們可以寫:

[TestMethod]
public void UnitTest()
{
    var mockService = new Mock<IService>();

    Func<IService> mockDelegate = () => mockService.Object;

    // The rest of the test
}

例外是因為Moq不支持這種情況。 但是,不是拋出NotSupportException而是InvalidCastException

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM