问题描述
我的代码中有以下调用:
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 的匹配?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!