gpt4 book ai didi

c# - 如何在谓词调用中测试与 FakeItEasy 的匹配?

转载 作者:太空狗 更新时间:2023-10-29 23:07:48 26 4
gpt4 key购买 nike

我的代码中有以下调用:

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(…) 在我的存储库中被调用并具有正确的函数。

所以我的测试看起来像这样:

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(...)

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

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

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

这是失败的,我得到的异常是

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

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

最佳答案

披露 - VasilisP 和我昨天聊了聊这个。

在某种程度上,这并不是真正的 FakeItEasy 问题。您在 A.CallTo 中设置参数匹配器的方法通话正常。问题是您提供的用于匹配谓词的 lambda 不起作用。这将问题归结为“我如何判断一个表达式是否是我想要的?”。

还有其他的StackOverflow问题会问类似这样的问题,比如

其中一种方法可能适合您。

但是,您看到的异常的直接原因是传入的谓词不是 BinaryExpression , 这是一个 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
}

不过,总的来说,我会警告不要像这样进行测试 - 它对我来说似乎有点脆弱。当然,您可能有充分的理由采用这种方法。但是,如果它适合您,另一种方法可能是只捕获谓词,然后通过让它针对已知的候选对象列表运行来询问它。如果它按照您想要的方式进行过滤,那么它就会通过。这样,如果有人以仍然有效的方式更改传入的谓词,可能是通过将运算符切换为 <。日期在左边,测试仍然有效。我只是把它作为另一种选择。

关于c# - 如何在谓词调用中测试与 FakeItEasy 的匹配?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21437044/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com