本文介绍了如何在谓词调用中测试与 FakeItEasy 的匹配?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的代码中有以下调用:

I have 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));

并且我正在尝试使用 FakeItEasy 来验证当 dateTimeFilter 具有值时,SearchFor(…) 在我的存储库中使用正确的函数被调用.

and I am trying to use FakeItEasy to verify that when the dateTimeFilter has a value, the SearchFor(…) is being called within my repository 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);

这是不正确的.有什么方法可以测试我是否使用正确的表达式调用 SearchFor(…)?

Which is not correct.What would be a way to test the whether or not I am calling SearchFor(…) with the correct expression?

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

传递给 SearchFor(...) 的实际值是 DateTime.MinValue 所以我把我的断言改为:

The actual value being passed into SearchFor(…) is DateTime.MinValue so I changed my assertion 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 is failing and the exception I am getting is

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

我不确定我做错了什么...

and I am not sure what I am doing wrong...

推荐答案

抱歉,我应该早点回答这个问题.确实,Blair Conrad 和我进行了一次聊天,他帮助我了解了如何更好地测试谓词.根据他的建议,我想出了以下解决方案.

Sorry I should have answered this earlier. It is true that Blair Conrad and I had a chat and he helped me understand how to test the predicates better. Based on his recommendation I came up with the following solution.

在我的测试中,我创建了一个辅助表达式提取器,如下所示:

In my tests I created a helper Expression extractor show below:

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();
}

然后在我的测试中我可以像这样做我的断言:

And then in my tests I could do my assert like this:

//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);

这篇关于如何在谓词调用中测试与 FakeItEasy 的匹配?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-04 07:20
查看更多