我可以在Moq中重用It.Any参数描述符吗?

时间:2015-03-15 14:16:46

标签: c# .net unit-testing moq

我有一些类似于

的代码
FooMock.Setup( m => m.Bar( It.Is<BarArg>( x => long_test_x_is_ok(x) ) );
天真地,我以为我可以把它重写为:

var barArg = It.Is<BarArg>( x => long_test_x_is_ok(x) );
FooMock.Setup( m => m.Bar( barArg ) );
但是,Moq并不爱我。有可能这样做吗?

同样,我们的一些类名很长。我想重构对

的调用
It.IsAny<AnnoyinglyLongClassNameHere>()

更短暂的

var anyAlcnh = It.IsAny<AnnoyinglyLongClassNameHere>;

似乎也无效。

1 个答案:

答案 0 :(得分:3)

它不起作用的原因是Setup实际上只是Expression<Action<IFoo>>而不是Action<IFoo>

它实际上从未调用您传入的Action,它的作用是将表达式拉开,将其拆开并解析每个组件。因此,你无法取出barArg,因为这会使barArg成为表达式解析器的“黑盒子”,并且不知道变量代表什么。

你能做的最好的事情是

//Assuming Bar has the signature "void Bar(BarArg barArg)". 
//If it was "Baz Bar(BarArg barArg)" use "Expression<Func<IFoo, Baz>>" instead.
Expression<Action<IFoo>> setup =  m => m.Bar(It.Is<BarArg>(x => long_test_x_is_ok(x)));
FooMock.Setup(setup);

IsAny也存在同样的问题,但是你可以使用别名来缩短类名。

//At the top of your file with your other using statements
using ShortName = Some.Namespace.AnnoyinglyLongClassNameHere;

//Down in your unit test
FooMock.Setup(m => m.Bar(It.IsAny<ShortName>());