I am trying to unit test code that uses SearchClient.SearchAsync()
method. I am using AutoFixture.AutoMoq nuget package.
Here is what I tried:
mockSearchClient.Setup(msc => msc.SearchAsync<MyModel>(
It.IsAny<string>(),
It.IsAny<SearchOptions>(),
It.IsAny<CancellationToken>()
)).Returns(Task.FromResult(<<PROBLEM HERE>>));
The problem lies in the parameter .Returns(Task.FromResult(<<PROBLEM HERE>>))
part. It expects a concrete object that is returned from the .SearchAsync()
method. According to docs and autocomplete, the method returns Azure.Response
which is an abstract class. So, I cannot new it up. In actuality, the method returns a descendant class Azure.ValueResponse
, which isn't abstract, but is internal to Azure SDK, so also impossible to new up.
So how does one mock the SearchClient.SearchAsync?
P.S. Using Azure.Search.Documents, v11.1.1.0
See https://github.com/Azure/azure-sdk-for-net/blob/master/sdk/core/Azure.Core/README.md#mocking for information. Basically, you can use Response.FromValue
along with the SearchModelFactory
(a pattern we follow with all our Azure.* client SDKs for models that can't be fully mocked with a constructor and/or settable properties) to create a mock like so (using Moq, since I'm unfamiliar with AutoMoq, but should be similar):
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);