[英]How to set up a concrete Expression<Func<TEntity, bool>> to a mock in a unit test through Moq?
我的存储库中有以下方法:
Task<TEntity> FirstOrDefaultAsync(
Expression<Func<TEntity, bool>> filter = null,
Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null,
CancellationToken cancellationToken = default);
我通过以下方式在服务中调用它:
var itemToUpdate = await _unitOfWork.ItemsRepository
.FirstOrDefaultAsync(x => x.Id == itemDto.Id && x.UserId == userId);
问题是如何在单元测试中调用它? 我对 ItemsRepository 有一个严格的模拟,当我这样调用它时,我得到一个异常,它是一个严格的模拟并且没有为我的场景设置:
ItemsRepositoryMock
.Setup(x => x.FirstOrDefaultAsync(x => x.Id == 1 && x.UserId == "ab70793b-cec8-4eba-99f3-cbad0b1649d0", null, CancellationToken.None))
.ReturnsAsync(firstItem);
我应该如何使用我想要的参数设置模拟?
简短的回答是你不能直接在 Moq 中设置它。 原因是就 c# 而言,这些表达式不相等。
你能做什么...
是编写您自己的表达式比较,并且根据该表达式中允许的内容,它可能更容易或更难。 你设置模拟
It.Is<Expression<Func<TheEntity, bool>>(actual=>CompareExpressions(actual, x=>x => x.Id == 1 && x.UserId == "ab70793b-cec8-4eba-99f3-cbad0b1649d0")
并实施
CompareExpressions<TEntity>(Func<TEntity, bool> actual,Func<TEntity, bool> expected)
遍历表达式树并在检测到差异时执行 Assert.Fail 并不是那么困难,但如果您之前没有这样做过,这可能是一个挑战,特别是如果您希望允许等效而不相同的表达式。 开始的好点是: ExpressionComparison
或者你可以编译表达式并用你可以做的匹配元素调用它
It.Is<Expression<Func<TheEntity, bool>>(actual=>CompareExpressions(actual, new[]{ new Sample<TheEntity>{ Subject= new TheEntity{ /*...*/ }, Expected = true, new Sample /*...*/ ) CompareExpressions(Func<TEntity, bool> actual, List<TEntity> samples) { var method = actual.Compile(); foreach(var sample in sampes) Assert.AreEqual(sample.Expected, method(sample.Subject)); }
第二种方法更容易,但如果您准备的样本不够好,则可能会出现误报。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.