请帮助这个Linq新手!
我正在测试中的类中创建一个列表,我想使用Moq检查结果。
我可以很容易地组合一个检查列表结果的谓词。然后,我如何将该谓词变成表达式?
var myList = new List<int> {1, 2, 3};
Predicate<List<int>> myPredicate = (list) =>
{
return list.Count == 3; // amongst other stuff
};
// ... do my stuff
myMock.Verify(m => m.DidStuffWith(It.Is<List<int>>( ??? )));
???需要是Expression<Predicate<List<int>>>
,如果你可以了解许多仿制药。我找到了相反的答案,并将表达式编译成谓词。但是,他们并没有帮助我更好地理解Linq。
答案 0 :(得分:5)
变化:
Predicate<List<int>> myPredicate = (list) => list.Count == 3;
要:
Expression<Predicate<List<int>>> myPredicate = (list) => list.Count == 3;
编译器为您带来了魔力。通过一些警告 1 ,任何只处理表达式(无块)的lambda都可以通过包装委托类型(在本例中为Predicate<List<int>>
)转换为表达式树)Expression<>
。如您所述,您可以通过调用myPredicate.Compile()
再次将其反转。
1 例如,async lambdas(即async () => await Task.Delay(1);
)无法转换为表达式树。
更新如果包含语句,您只需无法使用编译器到达所需的表达式树。您必须使用Expression
中的静态方法自己构建表达式树(更多工作)。 (Expression.Block
,Expression.IfThen
等。)
答案 1 :(得分:1)
Kirk Woll的回答直接解决了您的问题,但考虑到您可以在Callback
方法的Setup
上使用void
方法来处理传入的参数调用。这对我来说更有意义,因为你已经不得不构建一个方法来验证列表;它还为您提供了列表的本地副本。
//what is this list used for?
var myList = new List<int> {1, 2, 3};
List<int> listWithWhichStuffWasDone = null;
//other setup
myMock.Setup(m => m.DoStuffWith(It.IsAny<List<int>>()).
Callback<List<int>>(l => listWithWhichStufFWasDone = l);
objectUnderTest.MethodUnderTest();
myMock.Verify(m => m.DoStuffWith(It.IsAny<List<int>>()));
Validate(listWithWhichStuffWasDone);