在最小起订量中验证时允许*任何*参数值吗?
Allow *any* parameter value when verifying in Moq?
我正在验证是否使用 Moq 调用了一个方法,但它是一个相当复杂的方法签名,我只关心一个特定参数的值。我知道 Moq 有 It.IsAny<T>()
,但即使那样你仍然必须指定参数应该是什么类型。有没有办法只说 "I don't care what was passed as this parameter, in terms of type OR value"?
没有办法完成您的要求,因为 Setup
参数是一个表示强类型 C# 的表达式。例如,考虑以下方法:
void Main()
{
Setup(() => Foo(Any()));
}
void Setup(Expression<Action> expression)
{
}
void Foo(int i)
{
}
object Any()
{
throw new NotImplementedException();
}
此代码无法编译,因为 Any()
return 是一个 object
并且 Foo()
需要一个 int
参数。
如果我们尝试将 Any()
更改为 return dynamic
:
dynamic Any() {
throw new NotImplementedException();
}
这会产生以下错误:
CS1963 An expression tree may not contain a dynamic operation
如果不需要通用参数,根本无法使此表达式生成适用于所有可能的类型。
正如@StriplingWarrior 提到的,您必须在使用 Verify
.
时指定参数
然而,Moq 确实提供了 Invocations
序列(不确定引入的是哪个版本,YMMV),因此基本上可以满足您的要求。
对于以下接口:
public interface IFoo
{
public void Sum(int a, int b, out int sum);
}
...以下将断言 Sum
方法被调用一次 - 没有指定任何参数。
var fooMock = new Mock<IFoo>();
var foo = fooMock.Object;
foo.Sum(1, 2, out var sum);
Assert.That(fooMock.Invocations.Count(x => x.Method.Name.Equals(nameof(IFoo.Sum))), Is.EqualTo(1));
每个调用条目都有方法、参数等,因此您可以构建复杂的匹配项。
我正在验证是否使用 Moq 调用了一个方法,但它是一个相当复杂的方法签名,我只关心一个特定参数的值。我知道 Moq 有 It.IsAny<T>()
,但即使那样你仍然必须指定参数应该是什么类型。有没有办法只说 "I don't care what was passed as this parameter, in terms of type OR value"?
没有办法完成您的要求,因为 Setup
参数是一个表示强类型 C# 的表达式。例如,考虑以下方法:
void Main()
{
Setup(() => Foo(Any()));
}
void Setup(Expression<Action> expression)
{
}
void Foo(int i)
{
}
object Any()
{
throw new NotImplementedException();
}
此代码无法编译,因为 Any()
return 是一个 object
并且 Foo()
需要一个 int
参数。
如果我们尝试将 Any()
更改为 return dynamic
:
dynamic Any() {
throw new NotImplementedException();
}
这会产生以下错误:
CS1963 An expression tree may not contain a dynamic operation
如果不需要通用参数,根本无法使此表达式生成适用于所有可能的类型。
正如@StriplingWarrior 提到的,您必须在使用 Verify
.
然而,Moq 确实提供了 Invocations
序列(不确定引入的是哪个版本,YMMV),因此基本上可以满足您的要求。
对于以下接口:
public interface IFoo
{
public void Sum(int a, int b, out int sum);
}
...以下将断言 Sum
方法被调用一次 - 没有指定任何参数。
var fooMock = new Mock<IFoo>();
var foo = fooMock.Object;
foo.Sum(1, 2, out var sum);
Assert.That(fooMock.Invocations.Count(x => x.Method.Name.Equals(nameof(IFoo.Sum))), Is.EqualTo(1));
每个调用条目都有方法、参数等,因此您可以构建复杂的匹配项。