How to check compliance with FakeItEasy on a predicate call?

There is the following call in my code:

var dbResults = new List<CrossReferenceRelationshipEF>();
dbResults = dateTimeFilter == null
    ? new List<CrossReferenceRelationshipEF>(
        CrossReferenceRelationshipRepository.GetAll()
                .ToList().OrderBy(crr => crr.ToPartner))
    : new List<CrossReferenceRelationshipEF>(
        CrossReferenceRelationshipRepository.SearchFor(
            crr => crr.HistoricEntries
                .Any(he => he.ModifiedDatetime > dateTimeFilter))
                .ToList().OrderBy(crr => crr.ToPartner));

and I'm trying to use FakeItEasy to verify that when dateTimeFilterit matters, it is called in my repository SearchFor(…)with the correct function.

So my test looks something like this:

A.CallTo(() => crossReferenceRelationshipRepositoryMock.SearchFor(A<Expression<Func<CrossReferenceRelationshipEF,bool>>>.That
    .Matches(exp => Expression.Lambda<Func<DateTime>>(((BinaryExpression)exp.Body).Right).Compile().Invoke() == filterByDate)))
    .MustHaveHappened(Repeated.Exactly.Once);

This is not true. How can I check if I really call SearchFor(…)with the correct expression?

crr => crr.HistoricEntries.Any(he => he.ModifiedDatetime > dateTimeFilter)

The actual value passed in SearchFor(…)is equal DateTime.MinValue, so I changed my statement to:

A.CallTo(() => crossReferenceRelationshipRepositoryMock.SearchFor(A<Expression<Func<CrossReferenceRelationshipEF, bool>>>.That
    .Matches(exp => Expression.Lambda<Func<DateTime>>(((BinaryExpression)exp.Body).Right).Compile().Invoke() == DateTime.MinValue)))
    .MustHaveHappened(Repeated.Exactly.Once);

which does not work, and the exception that I get is

System.InvalidCastException:
  Unable to cast object of type 'System.Linq.Expressions.MethodCallExpressionN'
  to type 'System.Linq.Expressions.BinaryExpression'.

and I'm not sure what I'm doing wrong ...

+4
source share
2 answers

, . , , , . , .

Expression show :

private static string ExpressionExtractor(Expression<Func<CrossReferenceRelationshipEF, bool>> predicate)
{
    var expression = ((BinaryExpression) ((LambdaExpression) ((MethodCallExpression) predicate.Body).Arguments[1]).Body);
    var value = Expression.Lambda<Func<object>>(Expression.Convert(expression.Right, typeof (object))).Compile().Invoke();

    return value.ToString();
}

:

//Assert        
A.CallTo(() => crossReferenceRelationshipRepositoryMock.SearchFor(A<Expression<Func<CrossReferenceRelationshipEF, bool>>>.That
    .Matches(exp => ExpressionExtractor(exp) == "20/01/2014 14:06:55")))
    .MustHaveHappened(Repeated.Exactly.Twice);
+2

- VasilisP, .

, FakeItEasy. A.CallTo . , , , . , " , , ?".

StackOverflow, , ,

.

, , , pass-in BinaryExpression, a MethodCallExpression. , , , .

, , dateArgument :

public bool IsPredicateGood(Expression<Func<CrossReferenceRelationshipEF, bool>> predicate)
{
    var typedPredicate = (MethodCallExpression) predicate.Body;
    var innerPredicate = ((LambdaExpression)typedPredicate.Arguments[1]).Body;
    var dateArgument = ((BinaryExpression) innerPredicate).Right;
    return dateArgument != null; // not a real test yet, but you could adapt
}

, , : . , . , - , , -. , , . , - , , , < , . .

+3

Source: https://habr.com/ru/post/1524321/


All Articles