gpt4 book ai didi

linq - 能够使用查询表达式的模拟 IDocumentQuery

转载 作者:行者123 更新时间:2023-12-01 12:07:31 25 4
gpt4 key购买 nike

我需要能够模拟 IDocumentQuery,以便能够测试一段代码,查询文档集合并可能使用谓词来过滤它们:

IQueryable<T> documentQuery = client
.CreateDocumentQuery<T>(collectionUri, options);

if (predicate != null)
{
documentQuery = documentQuery.Where(predicate);
}

var list = documentQuery.AsDocumentQuery();
var documents = new List<T>();

while (list.HasMoreResults)
{
documents.AddRange(await list.ExecuteNextAsync<T>());
}

我使用了来自 https://stackoverflow.com/a/49911733/212121 的答案编写以下方法:

public static IDocumentClient Create<T>(params T[] collectionDocuments)
{
var query = Substitute.For<IFakeDocumentQuery<T>>();

var provider = Substitute.For<IQueryProvider>();

provider
.CreateQuery<T>(Arg.Any<Expression>())
.Returns(x => query);

query.Provider.Returns(provider);
query.ElementType.Returns(collectionDocuments.AsQueryable().ElementType);
query.Expression.Returns(collectionDocuments.AsQueryable().Expression);
query.GetEnumerator().Returns(collectionDocuments.AsQueryable().GetEnumerator());

query.ExecuteNextAsync<T>().Returns(x => new FeedResponse<T>(collectionDocuments));
query.HasMoreResults.Returns(true, false);

var client = Substitute.For<IDocumentClient>();

client
.CreateDocumentQuery<T>(Arg.Any<Uri>(), Arg.Any<FeedOptions>())
.Returns(query);

return client;
}

只要不使用 IQueryable.Where 过滤就可以正常工作。

我的问题:

Is there any way to capture predicate, that was used to create documentQuery and apply that predicate on collectionDocuments parameter?

最佳答案

从查询提供程序访问表达式,以便将其传递到后备集合以应用所需的过滤器。

查看以下内容

public static IDocumentClient Create<T>(params T[] collectionDocuments) {
var query = Substitute.For<IFakeDocumentQuery<T>>();

var queryable = collectionDocuments.AsQueryable();

var provider = Substitute.For<IQueryProvider>();
provider.CreateQuery<T>(Arg.Any<Expression>())
.Returns(x => {
var expression = x.Arg<Expression>();
if (expression != null) {
queryable = queryable.Provider.CreateQuery<T>(expression);
}
return query;
});

query.Provider.Returns(_ => provider);
query.ElementType.Returns(_ => queryable.ElementType);
query.Expression.Returns(_ => queryable.Expression);
query.GetEnumerator().Returns(_ => queryable.GetEnumerator());

query.ExecuteNextAsync<T>().Returns(x => new FeedResponse<T>(query));
query.HasMoreResults.Returns(true, true, false);

var client = Substitute.For<IDocumentClient>();

client
.CreateDocumentQuery<T>(Arg.Any<Uri>(), Arg.Any<FeedOptions>())
.Returns(query);

return client;
}

重要的部分是传递给查询的表达式用于在支持数据源(数组)上创建另一个查询的地方。

出于演示目的,使用以下示例对象进行测试。

public class SubjectUnderTest {
private readonly IDocumentClient client;

public SubjectUnderTest(IDocumentClient client) {
this.client = client;
}

public async Task<List<T>> Query<T>(Expression<Func<T, bool>> predicate = null) {
FeedOptions options = null; //for dummy purposes only
Uri collectionUri = null; //for dummy purposes only
IQueryable<T> documentQuery = client.CreateDocumentQuery<T>(collectionUri, options);

if (predicate != null) {
documentQuery = documentQuery.Where(predicate);
}

var list = documentQuery.AsDocumentQuery();
var documents = new List<T>();

while (list.HasMoreResults) {
documents.AddRange(await list.ExecuteNextAsync<T>());
}

return documents;
}
}

以下示例测试何时将表达式传递给查询

[TestMethod]
public async Task Should_Filter_DocumentQuery() {
//Arrange
var dataSource = Enumerable.Range(0, 3)
.Select(_ => new Document() { Key = _ }).ToArray();
var client = Create(dataSource);
var subject = new SubjectUnderTest(client);

Expression<Func<Document, bool>> predicate = _ => _.Key == 1;
var expected = dataSource.Where(predicate.Compile());

//Act
var actual = await subject.Query<Document>(predicate);

//Assert
actual.Should().BeEquivalentTo(expected);
}

public class Document {
public int Key { get; set; }
}

关于linq - 能够使用查询表达式的模拟 IDocumentQuery,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54929728/

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