0

目前

Moq用来创建一些模拟对象;到目前为止,一切都运行良好。目前使用我正在做的 Moq 来“分配”一个代表

var someMock = new Mock<ISomeInterface>();
someMock.Setup(x => x.DoSomething(It.IsAny<int>())).Returns(this.DoSomething)

this.DoSomething接受int参数的方法在哪里?基本上它的结构x.DoSomethingISomeInterface.

问题

是否可以简单地分配一个委托,而不需要指定其所有参数,即不使用 It.IsAny<int>()?理想情况下是这样的:

var someMock = new Mock<ISomeInterface>();
someMock.Setup(x => x.DoSomething).Returns(this.DoSomething)
4

1 回答 1

1

不,那是不可能的。这不是 Moq 的“缺点”——C# 不支持它。

一些背景:

假设ISomeInterface声明如下:

public interface ISomeInterface
{
    void Foo(int a, int b);
}

这意味着该Setup方法的参数必须是Func<ISomeInterface, Action<int, int>>.
现在的问题是该Setup方法必须以通用方式定义,因为您的方法可以具有任何类型的参数:

Setup<T1, T2>(Func<T, Action<T1, T2>> param)

T是 Mock 类的泛型类型,T1T2方法的参数。

然而,调用此方法将导致编译器错误:

Mock.Setup<T1, T2>(System.Func<UserQuery.ISomeInterface,System.Action<T1,T2>>)无法从用法中推断出方法的类型参数。尝试明确指定类型参数。

为了让它工作,你需要这样称呼它:

someMock.Setup<int, int>(x => x.DoSomething)

或像这样:

someMock.Setup(x => (Action<int, int>)x.DoSomething);

在这两种情况下,您都必须指定参数的类型,就像您现在所做的那样。

至于为什么会出现编译器错误:

x.DoSomething是一个方法组。存在到 的隐式转换Action<int, int>
但是,要执行此隐式转换,编译器需要知道 和 的T1类型T2。但是这些类型只能在转换发生后推断出来。
这两个步骤相互依赖,这就是它不起作用的原因。

于 2013-02-12T11:44:09.473 回答