Sigmundur
Sigmundur

Reputation: 897

UnitTesting Elasticsearch.net IElasticLowLevelClient

I have a very simple class that uses Elasticsearch.net to access an endpoint with a simple query. The class and method works fine and I get the expected results. But I am not successful in UnitTesting this class. Here is the class I am trying to UnitTest:

namespace X
{
public class YLookup : IYLookup
{
    private readonly IElasticLowLevelClient _lowLevelClient;
    public YLookup()
    {

    }
    public YLookup(IElasticLowLevelClient lowLevelClient)
    {
        _lowLevelClient = lowLevelClient;
    }

    public string Lookup(string Z)
    {
        if (string.IsNullOrEmpty(Z))
        {
            return string.Empty;
        }
        var searchResponse = _lowLevelClient.Search<StringResponse>(
            "person",
            "company",
            "My elastic search query");

        if (searchResponse.Success)
        {
            // success! Parse searchResponse.Body;
        }
        else
        {
            // Failure :(
        }
    }
}
}

The interface:

namespace X
{
internal interface IYLookup
{
    string Lookup(string Z);
}
}

The code I am using to try to UnitTest:

    [TestMethod]
    public void Test1()
    {
        string h = "{\r\n\t\"took\": 2,\r\n\t\"timed_out\": false,\r\n\t\"_shards\": {\r\n\t\t\"total\": 6,\r\n\t\t\"successful\": 6,\r\n\t\t\"failed\": 0\r\n\t},\r\n\t\"hits\": {\r\n\t\t\"total\": 0,\r\n\t\t\"max_score\": null,\r\n\t\t\"hits\": []\r\n\t}\r\n}";

        Mock<IApiCallDetails> apiCallDetails = new Mock<IApiCallDetails>(MockBehavior.Strict);
        apiCallDetails.Setup(x => x.Success).Returns(true);

        Mock<ElasticsearchResponse<string>> elasticsearchResponse = new Mock<ElasticsearchResponse<string>>();
        elasticsearchResponse.Setup(x => x.Body).Returns(h);

        Mock<StringResponse> s = new Mock<StringResponse>();
        s.Setup(x => x.ApiCall).Returns(apiCallDetails.Object);

        Mock<IElasticLowLevelClient> elasticLowLevelClient = new Mock<IElasticLowLevelClient>(MockBehavior.Strict);

        elasticLowLevelClient.Setup(x => x.Search<StringResponse>(It.IsAny<string>(), It.IsAny<string>(),, It.IsAny<PostData>(), It.IsAny<SearchRequestParameters>())).Returns(s.Object);
    }

The error I am having is:

invalid setup on a non-virtual (overridable in vb) member

I need to set the success property and the body property and I am not seeing how I can set the body with the complicated structure of the objects involved.

Does someone have a solution or can see what I am doing wrong? Thanks.

P.S. Please ignore naming. I have changed them to these meaningless names on purpose.

Upvotes: 1

Views: 674

Answers (1)

AlanT
AlanT

Reputation: 3663

From looking at the source (Elasticsearch-net on GitHub) you should be able to create an instance of StringResponse directly, passing in the Body in the ctor. The ApiCall property on the ElasticsearchResponseBase has a public get/set pair so you should be able to do something along the lines of

[TestMethod]
public void Test1()
{
    string h = "{\r\n\t\"took\": 2,\r\n\t\"timed_out\": false,\r\n\t\"_shards\": {\r\n\t\t\"total\": 6,\r\n\t\t\"successful\": 6,\r\n\t\t\"failed\": 0\r\n\t},\r\n\t\"hits\": {\r\n\t\t\"total\": 0,\r\n\t\t\"max_score\": null,\r\n\t\t\"hits\": []\r\n\t}\r\n}";

    Mock<IApiCallDetails> apiCallDetails = new Mock<IApiCallDetails>(MockBehavior.Strict);
    apiCallDetails.Setup(x => x.Success).Returns(true);

    var resp = new StringResponse(h);
    resp.ApiCall = apiCallDetails.Object;

    Mock<IElasticLowLevelClient> elasticLowLevelClient = new Mock<IElasticLowLevelClient>(MockBehavior.Strict);

    elasticLowLevelClient.Setup(x => x.Search<StringResponse>(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<PostData>(), It.IsAny<SearchRequestParameters>())).Returns(resp);
}

I have copied the code from above for the lowLevelClient setup (removing the extra comma) but if we want to check that search is being invoked correctly we should match them off to the actual parameters rather than using ().

Upvotes: 3

Related Questions