为 Cosmos 客户端编写单元测试时出错(无法将列表<model> 转换为任务<FeedResponse<model>>)
Error while writing Unit test for Cosmos Client ( Can not Convert List<model> to Task<FeedResponse<model>> )
包裹-
Microsoft.Azure.Cosmos.Client, Version=3.8.0.0
The Method I am trying to mock is -
public async Task LoadCollectionFromStorageAsync()
{
string query = "SELECT* FROM c";
QueryDefinition queryDefinition = new QueryDefinition(query);
FeedIterator<MyType> queryResultSetIterator = _client.GetContainer(_settings.CosmosDbDatabaseId, _settings.Table).GetItemQueryIterator<MyType>(queryDefinition);
List<MyType> results = new List<MyType>();
while (queryResultSetIterator.HasMoreResults)
{
results.AddRange(await queryResultSetIterator.ReadNextAsync());
}
}
下面是代码 --- 我收到错误的地方 ----
Mock<CosmosClient> _mockClient = new Mock<CosmosClient>();
Mock<Container>() _mockContainer = new Mock<Container>();
List<MyType> model = new List<MyType>();
{
PartitonKey= "p1",
Name = "name1"
};
_mockClient.Setup(_ => _.GetContainer(It.IsAny<string>(), It.IsAny<string>())).Returns(_mockContainer.Object);
_mockContainer.Setup(_ => _.GetItemQueryIterator<MyType>(It.IsAny<string>(), null, null).ReadNextAsync(It.IsAny<CancellationToken>()))
.Returns(model);
你在嘲笑 GetItemQueryIterator
which returns a FeedIterator
,当调用 ReadNextAsync
时,它 returns a FeedResponse<T>
,不是 List<T>
.
您可以这样做:
[TestMethod]
public async Task MyTestMethod()
{
List<MyType> results = new List<MyType>();
{
PartitonKey= "p1",
Name = "name1"
};
Mock<FeedResponse<MyType>> mockedResponse = new Mock<FeedResponse<MyType>>();
mockedResponse.Setup(r => r.Resource).Returns(results);
Mock<FeedIterator<MyType>> mockedIterator = new Mock<FeedIterator<MyType>>();
mockedIterator.Setup(q => q.ReadNextAsync(It.IsAny<CancellationToken>()))
.ReturnsAsync(() => mockedResponse.Object);
mockedIterator.SetupSequence(q => q.HasMoreResults)
.Returns(true)
.Returns(false);
while (mockedIterator.Object.HasMoreResults)
{
FeedResponse<MyType> feedresponse = await mockedIterator.Object.ReadNextAsync();
Assert.AreEqual(results, feedresponse.Resource);
}
Mock.Get(mockedIterator.Object)
.Verify(q => q.ReadNextAsync(It.IsAny<CancellationToken>()), Times.Once);
Mock.Get(mockedIterator.Object)
.Verify(q => q.HasMoreResults, Times.Exactly(2));
Mock.Get(mockedResponse.Object)
.Verify(r => r.Resource, Times.Once);
}
包裹-
Microsoft.Azure.Cosmos.Client, Version=3.8.0.0 The Method I am trying to mock is -
public async Task LoadCollectionFromStorageAsync()
{
string query = "SELECT* FROM c";
QueryDefinition queryDefinition = new QueryDefinition(query);
FeedIterator<MyType> queryResultSetIterator = _client.GetContainer(_settings.CosmosDbDatabaseId, _settings.Table).GetItemQueryIterator<MyType>(queryDefinition);
List<MyType> results = new List<MyType>();
while (queryResultSetIterator.HasMoreResults)
{
results.AddRange(await queryResultSetIterator.ReadNextAsync());
}
}
下面是代码 --- 我收到错误的地方 ----
Mock<CosmosClient> _mockClient = new Mock<CosmosClient>();
Mock<Container>() _mockContainer = new Mock<Container>();
List<MyType> model = new List<MyType>();
{
PartitonKey= "p1",
Name = "name1"
};
_mockClient.Setup(_ => _.GetContainer(It.IsAny<string>(), It.IsAny<string>())).Returns(_mockContainer.Object);
_mockContainer.Setup(_ => _.GetItemQueryIterator<MyType>(It.IsAny<string>(), null, null).ReadNextAsync(It.IsAny<CancellationToken>()))
.Returns(model);
你在嘲笑 GetItemQueryIterator
which returns a FeedIterator
,当调用 ReadNextAsync
时,它 returns a FeedResponse<T>
,不是 List<T>
.
您可以这样做:
[TestMethod]
public async Task MyTestMethod()
{
List<MyType> results = new List<MyType>();
{
PartitonKey= "p1",
Name = "name1"
};
Mock<FeedResponse<MyType>> mockedResponse = new Mock<FeedResponse<MyType>>();
mockedResponse.Setup(r => r.Resource).Returns(results);
Mock<FeedIterator<MyType>> mockedIterator = new Mock<FeedIterator<MyType>>();
mockedIterator.Setup(q => q.ReadNextAsync(It.IsAny<CancellationToken>()))
.ReturnsAsync(() => mockedResponse.Object);
mockedIterator.SetupSequence(q => q.HasMoreResults)
.Returns(true)
.Returns(false);
while (mockedIterator.Object.HasMoreResults)
{
FeedResponse<MyType> feedresponse = await mockedIterator.Object.ReadNextAsync();
Assert.AreEqual(results, feedresponse.Resource);
}
Mock.Get(mockedIterator.Object)
.Verify(q => q.ReadNextAsync(It.IsAny<CancellationToken>()), Times.Once);
Mock.Get(mockedIterator.Object)
.Verify(q => q.HasMoreResults, Times.Exactly(2));
Mock.Get(mockedResponse.Object)
.Verify(r => r.Resource, Times.Once);
}