How can I convert a Predicate<T> to an Expression<Predicate<T>> to use with Moq?

本秂侑毒 提交于 2019-12-01 17:09:09

Change:

Predicate<List<int>> myPredicate = (list) => list.Count == 3;

To:

Expression<Predicate<List<int>>> myPredicate = (list) => list.Count == 3;

The compiler does the magic for you. With some caveats1, any lambda dealing only with expressions (no blocks) can be converted into an expression tree by wrapping the delegate type (in this case Predicate<List<int>>) with Expression<>. As you noted, you could then invert it yet again by calling myPredicate.Compile().

1 For example, async lambdas (i.e. async () => await Task.Delay(1);) cannot be converted to an expression tree.

Update: You simply cannot use the compiler to arrive at the expression tree you want if it includes statements. You'll have to build up the expression tree yourself (a lot more work) using the static methods in Expression. (Expression.Block, Expression.IfThen, etc.)

Kirk Woll's answer directly addresses your question, but consider the fact that you can use the Callback method on a Setup of a void method to handle the parameters which were passed in on invocation. This makes more sense to me since you're already having to build a method to validate the list anyway; it also gives you a local copy of the list.

//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);
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!