gpt4 book ai didi

c# - 在使用 SQL 查询的单元测试中模拟 IDocumentQuery

转载 作者:太空狗 更新时间:2023-10-30 01:29:44 25 4
gpt4 key购买 nike

我正在使用单元测试来测试 DocumentDBRepository 类。我关注了this post作为 SQL 查询用例的示例。但它显示错误

Message: System.InvalidCastException : Unable to cast object of type 'System.Linq.EnumerableQuery to type 'Microsoft.Azure.Documents.Linq.IDocumentQuery

这是我的 DocumentDBRepository 类的代码

private IDocumentQuery<T> GetQueryBySQL(string queryStr)
{
var uri = UriFactory.CreateDocumentCollectionUri(_databaseId, _collectionId);
var feedOptions = new FeedOptions { MaxItemCount = -1, EnableCrossPartitionQuery = true };
IQueryable<T> filter = _client.CreateDocumentQuery<T>(uri, queryStr, feedOptions);
IDocumentQuery<T> query = filter.AsDocumentQuery();
return query;

}

public async Task<IEnumerable<T>> RunQueryAsync(string queryString)
{
IDocumentQuery<T> query = GetQueryBySQL(queryString);

List<T> results = new List<T>();

while (query.HasMoreResults)
{
results.AddRange(await query.ExecuteNextAsync<T>());
}
return results;
}

这是我的测试类的代码

public async virtual Task Test_GetEntitiesAsyncBySQL()
{
var id = "100";
string queryString = "SELECT * FROM c WHERE c.ID = " + id;
var dataSource = new List<Book> {
new Book { ID = "100", Title = "abc"}}.AsQueryable();


Expression<Func<Book, bool>> predicate = t => t.ID == id;
var expected = dataSource.Where(predicate.Compile());
var response = new FeedResponse<Book>(expected);

var mockDocumentQuery = new Mock<DocumentDBRepositoryTest.IFakeDocumentQuery<Book>>();

mockDocumentQuery
.SetupSequence(_ => _.HasMoreResults)
.Returns(true)
.Returns(false);

mockDocumentQuery
.Setup(_ => _.ExecuteNextAsync<Book>(It.IsAny<CancellationToken>()))
.ReturnsAsync(response);

var provider = new Mock<IQueryProvider>();
provider
.Setup(_ => _.CreateQuery<Book>(It.IsAny<Expression>()))
.Returns(mockDocumentQuery.Object);

mockDocumentQuery.As<IQueryable<Book>>().Setup(x => x.Provider).Returns(provider.Object);
mockDocumentQuery.As<IQueryable<Book>>().Setup(x => x.Expression).Returns(dataSource.Expression);
mockDocumentQuery.As<IQueryable<Book>>().Setup(x => x.ElementType).Returns(dataSource.ElementType);
mockDocumentQuery.As<IQueryable<Book>>().Setup(x => x.GetEnumerator()).Returns(() => dataSource.GetEnumerator());

var client = new Mock<IDocumentClient>();

client.Setup(_ => _.CreateDocumentQuery<Book>(It.IsAny<Uri>(), It.IsAny<FeedOptions>()))
.Returns(mockDocumentQuery.Object);

var documentsRepository = new DocumentDBRepository<Book>(client.Object, "100", "100");

//Act
var entities = await documentsRepository.RunQueryAsync(queryString);

//Assert
entities.Should()
.NotBeNullOrEmpty()
.And.BeEquivalentTo(expected);
}

断点停在这行代码:

IQueryable<T> filter = _client.CreateDocumentQuery<T>(uri, queryStr, feedOptions); 

当它应该显示我在测试方法中定义的预期值时,filter变量在其许多属性中显示空异常,并且结果 View 显示为空。

知道如何解决这个问题吗?

最佳答案

需要在模拟客户端上设置正确的 CreateDocumentQuery 重载。

被测方法使用

IQueryable<T> filter = _client.CreateDocumentQuery<T>(uri, queryStr, feedOptions); 

但是在安排测试时,客户端的设置如下

client
.Setup(_ => _.CreateDocumentQuery<Book>(It.IsAny<Uri>(), It.IsAny<FeedOptions>()))
.Returns(mockDocumentQuery.Object);

应该改为

client
.Setup(_ => _.CreateDocumentQuery<Book>(It.IsAny<Uri>(), It.IsAny<string>(), It.IsAny<FeedOptions>()))
.Returns(mockDocumentQuery.Object);

因为额外的queryStr参数。它也可以直接使用字符串参数作为替代方案,因为它被显式注入(inject)到方法中并且可以用作期望的一部分。

client
.Setup(_ => _.CreateDocumentQuery<Book>(It.IsAny<Uri>(), queryStr, It.IsAny<FeedOptions>()))
.Returns(mockDocumentQuery.Object);

由于正在测试的方法在构建查询时不直接使用 Linq,因此无需像本主题的先前迭代中那样模拟/覆盖查询提供程序

这是经过上述更改后完成的测试

public async virtual Task Test_GetEntitiesAsyncBySQL() {
//Arrange
var id = "100";
string queryString = "SELECT * FROM c WHERE c.ID = " + id;
var dataSource = new List<Book> {
new Book { ID = "100", Title = "abc"}
}.AsQueryable();

Expression<Func<Book, bool>> predicate = t => t.ID == id;
var expected = dataSource.Where(predicate.Compile());
var response = new FeedResponse<Book>(expected);

var mockDocumentQuery = new Mock<IFakeDocumentQuery<Book>>();

mockDocumentQuery
.SetupSequence(_ => _.HasMoreResults)
.Returns(true)
.Returns(false);

mockDocumentQuery
.Setup(_ => _.ExecuteNextAsync<Book>(It.IsAny<CancellationToken>()))
.ReturnsAsync(response);

//Note the change here
mockDocumentQuery.As<IQueryable<Book>>().Setup(_ => _.Provider).Returns(dataSource.Provider);
mockDocumentQuery.As<IQueryable<Book>>().Setup(_ => _.Expression).Returns(dataSource.Expression);
mockDocumentQuery.As<IQueryable<Book>>().Setup(_ => _.ElementType).Returns(dataSource.ElementType);
mockDocumentQuery.As<IQueryable<Book>>().Setup(_ => _.GetEnumerator()).Returns(() => dataSource.GetEnumerator());

var client = new Mock<IDocumentClient>();

//Note the change here
client
.Setup(_ => _.CreateDocumentQuery<Book>(It.IsAny<Uri>(), It.IsAny<string>(), It.IsAny<FeedOptions>()))
.Returns(mockDocumentQuery.Object);

var documentsRepository = new DocumentDBRepository<Book>(client.Object, "100", "100");

//Act
var entities = await documentsRepository.RunQueryAsync(queryString);

//Assert
entities.Should()
.NotBeNullOrEmpty()
.And.BeEquivalentTo(expected);
}

关于c# - 在使用 SQL 查询的单元测试中模拟 IDocumentQuery,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49935846/

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