Friday, July 1, 2016

Uniting Testing Expression Predicate with Moq

I recently was setting up a repository in a project with an interface on all repositories that took a predicate. As part of this I needed to mock out this call so I could unit test my code. The vast majority of samples out there for mocking an expression predicate just is It.IsAny<> which is not very helpful as it does not test anything other then verify it got a predicate. What if you actually want to test that you got a certain predicate though? It is actually pretty easy to do but not very straight forward.

Here is what you do for the It.IsAny<> approach in case someone is looking for that.

this.bindingRepository.Setup(c => c.Get(It.IsAny<Expression<Func<UserBinding, bool>>>())) 
.Returns(new List<UserBinding>() { defaultBinding }.AsQueryable());

This example just says to always return a collection of UserBindings that contain “defaultBinding” (which is an object I setup previously).

Here is what it looks like when you want to pass in an expression predicate that actually gets executed and only returns data if it matches something.

For my example I have a predicate that executes against an object collection of type “UserBinding.” The part to understand here is you are not passing to the Moq setup an expression. You are telling Moq to compile whatever expression it is given and see if that expression finds a match against the given object your provided. So in the example, does the expression passed in find a hit when executed against my “defaultBinding” object. If so return whatever data you want to return (in my case I am returning a collection of UserBindings as a queryable).

var defaultBinding = new UserBinding { Binding = new Binding { Name = "Default binding" }, Domain = "" };
this.bindingRepository.Setup(c => c.Get(It.Is<Expression<Func<UserBinding, bool>>>(y => y.Compile()(defaultBinding))))
.Returns(new List<UserBinding>() { defaultBinding }.AsQueryable());

That is it. Now you can test expression predicates and return different out put based on the expression you are expecting to be passed in.