c# – 使用SQL查询在单元测试中模拟IDocumentQuery
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了c# – 使用SQL查询在单元测试中模拟IDocumentQuery,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含5085字,纯文字阅读大概需要8分钟。
内容图文
我正在使用单元测试来测试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变量在很多属性上显示null异常,当结果视图显示我在测试方法中定义的期望值时,结果视图显示为空.
有任何线索如何修复它?
解决方法:
需要在模拟的客户端上设置正确的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参数.它也可以直接使用字符串参数作为替代,因为它被明确地注入到方法中并且可以用作期望的一部分.
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全部内容,希望文章能够帮你解决c# – 使用SQL查询在单元测试中模拟IDocumentQuery所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。