如何简化设置 Mocks 的 It.IsAny<T>() 参数
How to simplify the It.IsAny<T>() parameters for setting up Mocks
在我们的单元测试中,我们经常使用 Mock.Setup
。这会导致如下语句:
_mockedModel.Setup(x => x.Method1(It.IsAny<string>(), It.IsAny<object>(),It.IsAny<string>())).Returns(1);
_mockedModel.Setup(x => x.Method2(It.IsAny<string>(), It.IsAny<object>(), It.IsAny<object>())).Returns(1);
_mockedModel.Setup(x => x.Method3(It.IsAny<object>(), It.IsAny<object>(), It.IsAny<string>())).Returns(1);
_mockedModel.Setup(x => x.Method4(It.IsAny<object>(), It.IsAny<object>(), It.IsAny<object>())).Returns(1);
这很冗长,我想简化 It.IsAny<T>()
参数。
我们已尝试执行以下操作:
Func<string> s = It.IsAny<string>;
Func<object> o = It.IsAny<object>;
_mockedModel.Setup(x => x.Method1(s(), o(), o())).Returns(1);
_mockedModel.Setup(x => x.Method2(s(), o(), o())).Returns(1);
_mockedModel.Setup(x => x.Method3(o(), o(), s())).Returns(1);
_mockedModel.Setup(x => x.Method4(o(), o(), o())).Returns(1);
但是,虽然这不会给出任何错误,但它不会设置 Mock。例如。方法 1 到 4 return 0 而不是 1.
But, although this does not give any errors, it does not Setup the Mock. E.g. Methods 1 to 4 return 0 and not 1.
这是因为 Moq Setup
明确地在表达式中寻找 It.IsAny<T>()
静态方法调用,以便正确配置设置。这是设计使然。
通过在尝试简化表达式时更改为函数,您强制表达式调用方法调用,returns 泛型类型参数的默认值。
所以你的表达效果就变成了
_mockedModel.Setup(x => x.Method1(null, null, null)).Returns(1);
//...
@Nkosi 的回答帮助我想出了一个解决方案。解决方案是将 It.IsAny() 调用放在 属性(或方法)中:
private static string Str => It.IsAny<string>();
private static object Obj => It.IsAny<object>();
这使得代码可以这样写:
_mockedModel.Setup(x => x.Method1(Str, Obj, Obj)).Returns(1);
_mockedModel.Setup(x => x.Method2(Str, Obj, Obj)).Returns(1);
_mockedModel.Setup(x => x.Method3(Obj, Obj, Str)).Returns(1);
_mockedModel.Setup(x => x.Method4(Obj, Obj, Obj)).Returns(1);
在我们的单元测试中,我们经常使用 Mock.Setup
。这会导致如下语句:
_mockedModel.Setup(x => x.Method1(It.IsAny<string>(), It.IsAny<object>(),It.IsAny<string>())).Returns(1);
_mockedModel.Setup(x => x.Method2(It.IsAny<string>(), It.IsAny<object>(), It.IsAny<object>())).Returns(1);
_mockedModel.Setup(x => x.Method3(It.IsAny<object>(), It.IsAny<object>(), It.IsAny<string>())).Returns(1);
_mockedModel.Setup(x => x.Method4(It.IsAny<object>(), It.IsAny<object>(), It.IsAny<object>())).Returns(1);
这很冗长,我想简化 It.IsAny<T>()
参数。
我们已尝试执行以下操作:
Func<string> s = It.IsAny<string>;
Func<object> o = It.IsAny<object>;
_mockedModel.Setup(x => x.Method1(s(), o(), o())).Returns(1);
_mockedModel.Setup(x => x.Method2(s(), o(), o())).Returns(1);
_mockedModel.Setup(x => x.Method3(o(), o(), s())).Returns(1);
_mockedModel.Setup(x => x.Method4(o(), o(), o())).Returns(1);
但是,虽然这不会给出任何错误,但它不会设置 Mock。例如。方法 1 到 4 return 0 而不是 1.
But, although this does not give any errors, it does not Setup the Mock. E.g. Methods 1 to 4 return 0 and not 1.
这是因为 Moq Setup
明确地在表达式中寻找 It.IsAny<T>()
静态方法调用,以便正确配置设置。这是设计使然。
通过在尝试简化表达式时更改为函数,您强制表达式调用方法调用,returns 泛型类型参数的默认值。
所以你的表达效果就变成了
_mockedModel.Setup(x => x.Method1(null, null, null)).Returns(1);
//...
@Nkosi 的回答帮助我想出了一个解决方案。解决方案是将 It.IsAny() 调用放在 属性(或方法)中:
private static string Str => It.IsAny<string>();
private static object Obj => It.IsAny<object>();
这使得代码可以这样写:
_mockedModel.Setup(x => x.Method1(Str, Obj, Obj)).Returns(1);
_mockedModel.Setup(x => x.Method2(Str, Obj, Obj)).Returns(1);
_mockedModel.Setup(x => x.Method3(Obj, Obj, Str)).Returns(1);
_mockedModel.Setup(x => x.Method4(Obj, Obj, Obj)).Returns(1);