如何使用 Azure 认知搜索 SDK 模拟 SearchClient.SearchAsync?
How to mock SearchClient.SearchAsync with the Azure Cognitive Search SDK?
我正在尝试对使用 SearchClient.SearchAsync()
方法的代码进行单元测试。我正在使用 AutoFixture.AutoMoq nuget 包。
这是我尝试过的:
mockSearchClient.Setup(msc => msc.SearchAsync<MyModel>(
It.IsAny<string>(),
It.IsAny<SearchOptions>(),
It.IsAny<CancellationToken>()
)).Returns(Task.FromResult(<<PROBLEM HERE>>));
问题出在参数.Returns(Task.FromResult(<<PROBLEM HERE>>))
部分。它需要一个从 .SearchAsync()
方法返回的具体对象。根据文档和自动完成,方法 returns Azure.Response
是一个抽象 class。所以,我不能更新它。实际上,方法 returns 的后代 class Azure.ValueResponse
不是抽象的,而是 Azure SDK 内部的方法,因此也无法新建。
那么如何嘲笑 SearchClient.SearchAsync?
P.S。使用 Azure.Search.Documents、v11.1.1.0
有关信息,请参阅 https://github.com/Azure/azure-sdk-for-net/blob/master/sdk/core/Azure.Core/README.md#mocking。基本上,您可以使用 Response.FromValue
和 SearchModelFactory
(我们在所有 Azure.* 客户端 SDK 中都遵循的模式,用于无法使用构造函数 and/or 可设置属性完全模拟的模型) 来创建这样的模拟(使用 Moq,因为我不熟悉 AutoMoq,但应该类似):
var responseMock = new Mock<Response>();
var clientMock = new Mock<SearchClient>(() => new SearchClient(new Uri("https://localhost"), "index", new AzureKeyCredential("key")));
clientMock.SetupGet(x => x.IndexName).Returns("index");
clientMock.Setup(x => x.SearchAsync<Hotel>(
It.IsAny<string>(),
It.IsAny<SearchOptions>(),
It.IsAny<CancellationToken>()
))
.Returns(
Task.FromResult(
Response.FromValue(
SearchModelFactory.SearchResults(new[]
{
SearchModelFactory.SearchResult(new Hotel("1", "One"), 0.9, null),
SearchModelFactory.SearchResult(new Hotel("2", "Two"), 0.8, null),
},
100,
null,
null,
responseMock.Object),
responseMock.Object)));
var results = await clientMock.Object.SearchAsync<Hotel>("test").ConfigureAwait(false);
var hotels = results.Value;
Assert.Equal(2, hotels.GetResults().Count());
Assert.Equal(100, hotels.TotalCount);
我正在尝试对使用 SearchClient.SearchAsync()
方法的代码进行单元测试。我正在使用 AutoFixture.AutoMoq nuget 包。
这是我尝试过的:
mockSearchClient.Setup(msc => msc.SearchAsync<MyModel>(
It.IsAny<string>(),
It.IsAny<SearchOptions>(),
It.IsAny<CancellationToken>()
)).Returns(Task.FromResult(<<PROBLEM HERE>>));
问题出在参数.Returns(Task.FromResult(<<PROBLEM HERE>>))
部分。它需要一个从 .SearchAsync()
方法返回的具体对象。根据文档和自动完成,方法 returns Azure.Response
是一个抽象 class。所以,我不能更新它。实际上,方法 returns 的后代 class Azure.ValueResponse
不是抽象的,而是 Azure SDK 内部的方法,因此也无法新建。
那么如何嘲笑 SearchClient.SearchAsync?
P.S。使用 Azure.Search.Documents、v11.1.1.0
有关信息,请参阅 https://github.com/Azure/azure-sdk-for-net/blob/master/sdk/core/Azure.Core/README.md#mocking。基本上,您可以使用 Response.FromValue
和 SearchModelFactory
(我们在所有 Azure.* 客户端 SDK 中都遵循的模式,用于无法使用构造函数 and/or 可设置属性完全模拟的模型) 来创建这样的模拟(使用 Moq,因为我不熟悉 AutoMoq,但应该类似):
var responseMock = new Mock<Response>();
var clientMock = new Mock<SearchClient>(() => new SearchClient(new Uri("https://localhost"), "index", new AzureKeyCredential("key")));
clientMock.SetupGet(x => x.IndexName).Returns("index");
clientMock.Setup(x => x.SearchAsync<Hotel>(
It.IsAny<string>(),
It.IsAny<SearchOptions>(),
It.IsAny<CancellationToken>()
))
.Returns(
Task.FromResult(
Response.FromValue(
SearchModelFactory.SearchResults(new[]
{
SearchModelFactory.SearchResult(new Hotel("1", "One"), 0.9, null),
SearchModelFactory.SearchResult(new Hotel("2", "Two"), 0.8, null),
},
100,
null,
null,
responseMock.Object),
responseMock.Object)));
var results = await clientMock.Object.SearchAsync<Hotel>("test").ConfigureAwait(false);
var hotels = results.Value;
Assert.Equal(2, hotels.GetResults().Count());
Assert.Equal(100, hotels.TotalCount);