构建用于单元测试的LINQ表达式
本文关键字:LINQ 表达式 单元测试 用于 构建 | 更新日期: 2023-09-27 18:25:08
我正在为一个类编写一些单元测试,我正在测试的方法接受一个表达式,我试图构建和表达式并将其传递给该方法,但我得到了以下错误:
System.ArgumentException:静态方法需要null实例,非静态方法需要非null实例。参数名称:方法
[TestClass]
public class WhenFilterProvided : FindSubscriptionsForCurrentUserTestBase
{
bool filterFuncWasCalled;
private Func<UserSubscription, bool> filterFunc => (userSubscription) =>
{
filterFuncWasCalled = true;
return userSubscription.SubscriptionId == "petrol.prcies.monthly";
};
protected override Expression<Func<UserSubscription, bool>> Filter =>
Expression.Lambda<Func<UserSubscription, bool>>(Expression.Call(filterFunc.Method));
[TestMethod]
public void CallsDetailsRepository()
{
UserDetailsRepositoryMock.Verify(x => x.FindAsync("userId", CancellationToken.None), Times.Once);
}
[TestMethod]
public void FilterFuncGetsCalledToFilterSubscriptions()
{
Assert.IsTrue(filterFuncWasCalled);
}
}
匿名方法有时作为实例方法来实现。在您的情况下,匿名方法必须是实例方法,因为您需要访问this
才能访问filterFuncWasCalled
。因此,您试图调用一个实例方法,但没有传递任何实例。您可以通过传递一个带有实例的常量表达式来解决这个问题:
Expression.Call(Expression.Constant(filterFunc.Target), filterFunc.Method)
但这也不起作用,因为该方法接受一个参数,而您没有传递任何参数。让我们使用与lambda表达式相同的表达式。这是实现这一点的完整Filter
属性:
Expression<Func<UserSubscription, bool>> Filter {
get {
var param = Expression.Parameter(typeof(UserSubscription));
var body = Expression.Call(Expression.Constant(filterFunc.Target), filterFunc.Method, param);
return Expression.Lambda<Func<UserSubscription, bool>>(body, param);
}
}