Search code examples
c#unit-testingelasticsearchobservablenest

Unit testing Elastic Search Nest client - BulkAll


I am writing a unit test for the ElasticSearch Nest .net client.

I have the following call inside a repository class

var observable = _client.BulkAll(documents,
    selector => selector
        .BackOffTime("30s")
        .BackOffRetries(2)
        .RefreshOnCompleted()
        .Size(1000)
    ).Wait(
        TimeSpan.FromMinutes(15),
        next => {
            _logger.LogInformation($"Adding {next.Items.Count} number of items");
    });

In my unit test I have :

client = Substitute.For<IElasticClient>();
await _repository.AddDocuments(documents);
_client.Received().BulkAll(Arg.Any<IBulkAllRequest<Purchase>);

But I get the following exception when running my unit test

Value cannot be null. (Parameter 'observable')
   at Nest.Extensions.ThrowIfNull[T](T value, String name, String message)

I'm not sure how to correctly structure my unit test.

Any help much appreciated


Solution

  • I think your issue is the fact that you are working with the overload of BulkAll with this signature

    public BulkAllObservable<T> BulkAll<T>(IEnumerable<T> documents, Func<BulkAllDescriptor<T>, IBulkAllRequest<T>> selector, CancellationToken cancellationToken = default)
    

    but you prepare a substitute for this one

    public BulkAllObservable<T> BulkAll<T>(IBulkAllRequest<T> request, CancellationToken cancellationToken = default)
    

    To fix the issue I would configure a substitute in the following manner

    elasticClient
        .Received()
        .BulkAll(
            Arg.Any<IEnumerable<Document>>(),
            Arg.Any<Func<BulkAllDescriptor<Document>, IBulkAllRequest<Document>>>());
    

    Where Document type needs to be replaced with the type you are actually using.