如何使用 Moq 模拟带有 lambda 表达式的服务调用
How to mock a service call with a lambda expression using Moq
我正在使用 Moq 尝试模拟一个将 lambda 表达式作为其可选参数并调用数据库的方法。
这是我试图模拟的真实方法
public IQueryable<T> AllSearchBy<T>(params Expression<Func<T, bool>>[] search) where T : class
{
IQueryable<T> result = _context.Set<T>();
foreach (var item in search)
{
result = result.Where(item);
}
return result;
}
这是我的最小起订量存储库设置
var mockRepository = new Mock<IRepository>();
var rateEndHsbSlcTable = new List<Rate_End_HSB_SLC>
{
new Rate_End_HSB_SLC
{
Limit = 10000,
DwellingAgeMin = 0,
DwelilngAgeMax = 25,
Premium = 22M
},
new Rate_End_HSB_SLC
{
Limit = 10000,
DwellingAgeMin = 26,
DwelilngAgeMax = 50,
Premium = 45M
}
};
mockRepository.Setup(m => m.AllSearchBy(It.IsAny<Expression<Func<Rate_End_HSB_SLC, bool>>>()))
.Returns((Expression<Func<Rate_End_HSB_SLC, bool>> predicate) => rateEndHsbSlcTable.Where(predicate.Compile()).AsQueryable());
IRateServices rateService = new RateServices(mockRepository.Object, new HelperServices(mockRepository.Object));
这是我正在测试的代码中的调用,它给我一个错误(为简单起见,我用硬值替换了变量)
var test = _repository.AllSearchBy<Rate_End_HSB_SLC>(x => x.Limit == 10000 && x.DwellingAgeMin <= 19 && x.DwelilngAgeMax >= 19);
编译成功,但运行时出现以下异常
System.ArgumentException: Object of type
'System.Linq.Expressions.Expression1[System.Func
2[Twico.DataAccess.Rate_End_HSB_SLC,System.Boolean]][]'
cannot be converted to type
'System.Linq.Expressions.Expression1[System.Func
2[Twico.DataAccess.Rate_End_HSB_SLC,System.Boolean]]'.
我怀疑问题出在我的设置上,return 类型不正确。
对我做错了什么有什么想法吗?
编辑:使用 ibebbs 答案,我让它可以使用这种语法!
mockRepository.Setup(m => m.AllSearchBy(It.IsAny<Expression<Func<Rate_End_HSB_SLC, bool>>[]>()))
.Returns((Expression<Func<Rate_End_HSB_SLC, bool>>[] predicates) => predicates.Aggregate(rateEndHsbSlcTable, (source, predicate) => source.Where(predicate.Compile()).ToList()).AsQueryable());
快速查看代码显示 AllSearchBy
需要一个 数组 的 Expression<Func<T, bool>>
但您的设置指定了一个表达式。
也许试试这样的方法?
mockRepository
.Setup(m => m.AllSearchBy(It.IsAny<Expression<Func<Rate_End_HSB_SLC, bool>>[]>()))
.Returns(predicates => predicates
.Aggregate(
rateEndHsbSlcTable,
(source, predicate) => source.Where(predicate.Compile())).AsQueryable());
我正在使用 Moq 尝试模拟一个将 lambda 表达式作为其可选参数并调用数据库的方法。
这是我试图模拟的真实方法
public IQueryable<T> AllSearchBy<T>(params Expression<Func<T, bool>>[] search) where T : class
{
IQueryable<T> result = _context.Set<T>();
foreach (var item in search)
{
result = result.Where(item);
}
return result;
}
这是我的最小起订量存储库设置
var mockRepository = new Mock<IRepository>();
var rateEndHsbSlcTable = new List<Rate_End_HSB_SLC>
{
new Rate_End_HSB_SLC
{
Limit = 10000,
DwellingAgeMin = 0,
DwelilngAgeMax = 25,
Premium = 22M
},
new Rate_End_HSB_SLC
{
Limit = 10000,
DwellingAgeMin = 26,
DwelilngAgeMax = 50,
Premium = 45M
}
};
mockRepository.Setup(m => m.AllSearchBy(It.IsAny<Expression<Func<Rate_End_HSB_SLC, bool>>>()))
.Returns((Expression<Func<Rate_End_HSB_SLC, bool>> predicate) => rateEndHsbSlcTable.Where(predicate.Compile()).AsQueryable());
IRateServices rateService = new RateServices(mockRepository.Object, new HelperServices(mockRepository.Object));
这是我正在测试的代码中的调用,它给我一个错误(为简单起见,我用硬值替换了变量)
var test = _repository.AllSearchBy<Rate_End_HSB_SLC>(x => x.Limit == 10000 && x.DwellingAgeMin <= 19 && x.DwelilngAgeMax >= 19);
编译成功,但运行时出现以下异常
System.ArgumentException: Object of type 'System.Linq.Expressions.Expression
1[System.Func
2[Twico.DataAccess.Rate_End_HSB_SLC,System.Boolean]][]' cannot be converted to type 'System.Linq.Expressions.Expression1[System.Func
2[Twico.DataAccess.Rate_End_HSB_SLC,System.Boolean]]'.
我怀疑问题出在我的设置上,return 类型不正确。
对我做错了什么有什么想法吗?
编辑:使用 ibebbs 答案,我让它可以使用这种语法!
mockRepository.Setup(m => m.AllSearchBy(It.IsAny<Expression<Func<Rate_End_HSB_SLC, bool>>[]>()))
.Returns((Expression<Func<Rate_End_HSB_SLC, bool>>[] predicates) => predicates.Aggregate(rateEndHsbSlcTable, (source, predicate) => source.Where(predicate.Compile()).ToList()).AsQueryable());
快速查看代码显示 AllSearchBy
需要一个 数组 的 Expression<Func<T, bool>>
但您的设置指定了一个表达式。
也许试试这样的方法?
mockRepository
.Setup(m => m.AllSearchBy(It.IsAny<Expression<Func<Rate_End_HSB_SLC, bool>>[]>()))
.Returns(predicates => predicates
.Aggregate(
rateEndHsbSlcTable,
(source, predicate) => source.Where(predicate.Compile())).AsQueryable());