Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using Expression Trees as an argument constraint

Tags:

c#

fakeiteasy

Can I use an Expression Tree as an argument constraint in a FakeIteasy CallTo assertion?

Given a method on an interface with the following signature:

interface IRepository<TEntity>
{
    TEntity Single(Expression<Func<TEntity, bool>> predicate);

Being called in code like so:

Flight flight = repository.Single(f => f.ID == id);

I have in mind a unit test doing something like this:

Expression<Func<Flight, bool>> myExpression = flight => flight.ID == 1;

A.CallTo(() => repository.Single(
                  A<Expression<Func<Flight, bool>>>.That.Matches(myExpression)))
                  .Returns(new Flight());

However this produces a warning: Try specifying type arguments explicitly.

I am currently having to use the Ignored property which is not ideal.

like image 749
Michael.McD Avatar asked Feb 14 '26 19:02

Michael.McD


2 Answers

The "Matches"-method takes a lambda but you're trying to pass it the expression. What are you trying to say with the "Matches"-call? Are you matching on equality? In that case you'd just write:

A.CallTo(() => repository.Single(myExpression)).Returns(new Flight());

If you want to constrain the expression on something else you'd have to pass a predicate of the type: Func<Expression<Func<Flight, bool>>, bool> to the "Matches"-method.

like image 184
Patrik Hägne Avatar answered Feb 16 '26 08:02

Patrik Hägne


Thanks Patrik,

Examining the expression was exactly what I needed to do, i.e. parse the expression (f => f.ID == id) and execute the Right side of the == to get its runtime value.

In code this looks like this:

A.CallTo(() => flightRepository.Single(A<Expression<Func<Flight, bool>>>.That
                .Matches(exp => Expression.Lambda<Func<int>>(((BinaryExpression)exp.Body).Right).Compile().Invoke() == 1)))
                .Returns(new Flight());

However I can't help thinking that there must be a more elegant way to achieve the same end. I'll leave that for another day though.

Thanks again, Michael McDowell

like image 33
Michael.McD Avatar answered Feb 16 '26 08:02

Michael.McD



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!