Linq 能够使用查询表达式的模拟IDocumentQuery
我需要能够模拟Linq 能够使用查询表达式的模拟IDocumentQuery,linq,azure-cosmosdb,nsubstitute,Linq,Azure Cosmosdb,Nsubstitute,我需要能够模拟IDocumentQuery,能够测试查询文档集合并可能使用谓词过滤它们的代码段: IQueryable<T> documentQuery = client .CreateDocumentQuery<T>(collectionUri, options); if (predicate != null) { documentQuery = documentQuery.Where(predicate); } var lis
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>());
}
IQueryable documentQuery=客户端
.CreateDocumentQuery(collectionUri,选项);
if(谓词!=null)
{
documentQuery=documentQuery.Where(谓词);
}
var list=documentQuery.AsDocumentQuery();
var documents=新列表();
while(list.HasMoreResults)
{
documents.AddRange(wait list.ExecuteNextAsync());
}
我使用了来自的答案来编写以下方法:
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;
}
公共静态IDocumentClient创建(参数T[]collectionDocuments)
{
var query=Substitute.For();
var provider=Substitute.For();
供应商
.CreateQuery(Arg.Any())
.Returns(x=>query);
query.Provider.Returns(Provider);
返回(collectionDocuments.AsQueryable().ElementType);
Expression.Returns(collectionDocuments.AsQueryable().Expression);
query.GetEnumerator().Returns(collectionDocuments.AsQueryable().GetEnumerator());
返回(x=>newfeedresponse(collectionDocuments));
query.HasMoreResults.Returns(true、false);
var client=Substitute.For();
客户
.CreateDocumentQuery(Arg.Any(),Arg.Any())
.返回(查询);
返回客户;
}
只要不使用IQueryable.Where
进行过滤,它就可以正常工作
我的问题:
是否有任何方法可以捕获用于创建documentQuery
并将该谓词应用于collectionDocuments
参数的谓词
从查询提供程序访问表达式,以便将其传递到支持集合以应用所需的筛选器 回顾以下内容
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;
}
公共静态IDocumentClient创建(参数T[]collectionDocuments){
var query=Substitute.For();
var queryable=collectionDocuments.AsQueryable();
var provider=Substitute.For();
CreateQuery(Arg.Any())
.Returns(x=>{
var表达式=x.Arg();
if(表达式!=null){
queryable=queryable.Provider.CreateQuery(表达式);
}
返回查询;
});
返回(=>Provider);
返回(=>queryable.ElementType);
Expression.Returns(=>queryable.Expression);
query.GetEnumerator().Returns(=>queryable.GetEnumerator());
ExecuteNextAsync().返回(x=>newfeedresponse(query));
query.HasMoreResults.Returns(true、true、false);
var client=Substitute.For();
客户
.CreateDocumentQuery(Arg.Any(),Arg.Any())
.返回(查询);
返回客户;
}
重要的部分是,传递给查询的表达式用于在备份数据源(数组)上创建另一个查询
出于演示目的,使用以下示例测试对象
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;
}
}
公共类SubjectUnderTest{
私有只读IDocumentClient客户端;
公共SubjectionTest(IDocumentClient客户端){
this.client=client;
}
公共异步任务查询(表达式谓词=null){
FeedOptions=null;//仅用于虚拟目的
Uri collectionUri=null;//仅用于虚拟目的
IQueryable documentQuery=client.CreateDocumentQuery(collectionUri,选项);
if(谓词!=null){
documentQuery=documentQuery.Where(谓词);
}
var list=documentQuery.AsDocumentQuery();
var documents=新列表();
while(list.HasMoreResults){
documents.AddRange(wait list.ExecuteNextAsync());
}
归还文件;
}
}
以下示例测试将表达式传递到查询时的情况
[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; }
}
[TestMethod]
公共异步任务应该\u Filter\u DocumentQuery(){
//安排
var数据源=可枚举的范围(0,3)
.Select(=>newdocument(){Key=}).ToArray();
var client=Create(数据源);
var subject=新SubjectUnderTest(客户机);
表达式谓词=\u=>\ u0.Key==1;
var expected=dataSource.Where(predicate.Compile());
//表演
var-actual=wait-subject.Query(谓词);
//断言
实际的.Should().beequivalento(预期的);
}
公共类文档{
公共int密钥{get;set;}
}
精彩的答案,我想这是我第一次看到我的问题的答案和解决方案,其中还包括单元测试。谢谢。