3

I'm trying to find out a way to unit test the search results from the SearchResults<T> Class with different parameters.

Compared to DocumentSearchResult<T> Class which was in the previous package Microsoft.Azure.Search.Data v10.1.0, SearchResults<T> Class does not have any constructors, just properties and methods.

DocumentSearchResult<T> Class https://learn.microsoft.com/en-us/dotnet/api/microsoft.azure.search.models.documentsearchresult-1?view=azure-dotnet

SearchResults<T> Class https://learn.microsoft.com/en-us/dotnet/api/azure.search.documents.models.searchresults-1?view=azure-dotnet

I couldn't seem to find any documentation on that online as it is relatively new, but any ideas or suggestions are most welcome.

Thank you.

Mezo
  • 85
  • 6

2 Answers2

2

All our Azure SDKs for .NET matching package names Azure.* like Azure.Search.Documents are mockable using the same principles as shown here. For pure response objects like SearchResults<T>, we create model factories so that you can create them for testing. In general, there is no other intended purpose for creating them apart from testing.

Using Moq, for example:

// Arrange
var mockResponse = new Mock<Response>();
var mockResults = SearchModelFactory.SearchResults<Model>(new[]
{
  SearchModelFactory.SearchResult<Model>(new Model { Name = "a" }, 1.0),
  SearchModelFactory.SearchResult<Model>(new Model { Name = "b" }, 0.9),
}, 2, rawResponse: response.Object);

var mockClient = new Mock<SearchClient>();
mockClient.Setup(m => m.Search<Model>(It.IsAny<string>(), It.IsAny<SearchOptions>(), default))
  .Returns(Response.FromValue(mockResults, mockResponse.Object));

// Act
var response = mockClient.Object.Search<Model>("anything");

// Assert
Assert.AreEqual(2, response.Value.TotalCount);

See more mocking samples for other ideas.

Heath
  • 2,986
  • 18
  • 21
0

The SearchModelFactory is the class that will help you to create the models for SearchResults.

This reading can also be helpful for another kind of tests: https://devblogs.microsoft.com/azure-sdk/unit-testing-and-mocking/

Just in case someone else is looking for a version using NSubstitute, here is mine:

public async Task TheTest()
{
    // Arrange
    var searchResultValues = new List<SearchResult<MyModel>>
    {
        SearchModelFactory.SearchResult<MyModel>(new MyModel{Id = 1}, score:0.9, highlights:null),
        SearchModelFactory.SearchResult<MyModel>(new MyModel{Id = 2}, score:0.8, highlights:null),
    };
    var searchResults = SearchModelFactory.SearchResults<MyModel>(searchResultValues, totalCount: 2, facets: null, coverage: 1.3, rawResponse: Substitute.For<Response>());
    var response = Response.FromValue(searchResults, Substitute.For<Response>());

    var searchClient = Substitute.For<SearchClient>();
    searchClient.SearchAsync<MyModel>(Arg.Any<string>(), Arg.Any<SearchOptions>()).Returns(Task.FromResult(response));

    var sut = new ClassThatUsesTheSearchClient(searchClient);

    // Act
    var result = await sut.MethodToSearch();
    // or directly 
    var directResult = await searchClient.SearchAsync<MyModel>("text");

    // Assert
    Assert.AreEqual(2, directResult.Value.TotalCount);
    ...
}
forero08
  • 1
  • 1
  • 3