gpt4 book ai didi

c# - 如何在 Moq 中模拟链式 Linq 方法

转载 作者:太空宇宙 更新时间:2023-11-03 12:27:38 38 4
gpt4 key购买 nike

我有一个查询

var myRecord = myRepository.All().Any(e => e.Id == id);

我用这个来 mock 它

this._myMockRepository
.Setup(s => s.All().Any(It.IsAny<Expression<Func<MyObject, bool>>>()))
.Returns(this.GetFakeMyObjects().Any(t => t.Id == 1));

如何模拟 .All().Any(...) 调用?我得到的异常是 NotSupportedException 消息:

Expression references a method that does not belong to the mocked object: s => s.All().Any < MyRepositoryObject > (It.IsAny < Expression`1 > ())

我试过这样分解它

this._myMockRepository
.Setup(s => s.All(It.IsAny<Expression<Func<MyObject, bool>>>()))
.Returns(this.GetFakeMyObjects());
this._myMockRepository
.Setup(s => s.All().Any(It.IsAny<Expression<Func<MyObject, bool>>>()))
.Returns(this.GetFakeMyObjects().Any(t => t.Id == 1));

对于 Moq 来说还很新,所以任何提示都将不胜感激。

最佳答案

更新

如果 All() 不是扩展方法,则更新模拟设置以在调用时返回可查询。

this._myMockRepository
.Setup(_ => _.All())
.Returns(this.GetFakeMyObjects());//<-- assuming GetFakeMyObjects returns an enumerable

这假设一个存储库定义了类似的东西

public interface IRepository {
IEnumerable<MyObject> All();
}

或接近该定义。


原始答案

这些都是扩展方法。 Moq 不模拟扩展方法。

您需要模拟的是调用模拟成员时返回的满足提供的 linq 查询的内容。

基于代码片段的假设表明模拟的主题是可枚举的。

以下扩展方法可用于模拟在可枚举模拟上执行查询所需的行为。

/// <summary>
/// Converts a generic <seealso cref="System.Collections.Generic.IEnumerable&lt;T&gt;"/> to a <see cref="Moq.Mock"/> implementation of queryable list
/// </summary>
public static Mock<T> SetupQueryable<T, TItem>(this Mock<T> queryableMock, IEnumerable<TItem> source)
where T : class, IEnumerable<TItem> {

var queryableList = source.AsQueryable();

queryableMock.As<IQueryable<TItem>>().Setup(x => x.Provider).Returns(queryableList.Provider);
queryableMock.As<IQueryable<TItem>>().Setup(x => x.Expression).Returns(queryableList.Expression);
queryableMock.As<IQueryable<TItem>>().Setup(x => x.ElementType).Returns(queryableList.ElementType);
queryableMock.As<IQueryable<TItem>>().Setup(x => x.GetEnumerator()).Returns(() => queryableList.GetEnumerator());

return queryableMock;
}

并且可以像这样使用。

var fakeItems = GetFakeMyObjects();
var _myMockRepository = new Mock<IMyRepository>()
_myMockRepository.SetupQueryable(fakeItems);

这将允许在测试时在模拟对象上调用查询。

var myRepository = _myMockRepository.Object;
var myRecord = myRepository.All().Any(e => e.Id == id);

关于c# - 如何在 Moq 中模拟链式 Linq 方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43982574/

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