Search code examples
unit-testinggoelasticsearch

How to mock the elastic search SDK for go?


I'm developing an api in go, which communicates with elastic search using SDK v8. But I'm having difficulty simulating elastic methods for unit tests

I have the following function:

func DocumentExists(id string) (bool, error) {
  exists, err := elastic.Client.Exists("my_index", "doc_id")
  if err != nil {
    return false, err
  }
  if exists.StatusCode != 200 {
    return false, nil
  }

  return true, nil
}

This function only checks if a document exists in elastic. elastic.Client is provided globally for use anywhere in the application and has this type:

import  elastic "github.com/elastic/go-elasticsearch/v8"
var (
  Client             *elastic.Client
)

You can try to mock in different ways, using mock to testify. Unsuccessfully.

How could I do this? Should I change the way I obtain the Client? Using contracts?

It seems to me that using contracts would not be necessary in this case.


Solution

  • The official example in the Elasticsearch Go client's GitHub repository demonstrates how to create a mock for the Elasticsearch client. This process primarily entails invoking NewClient with a configuration that substitutes the HTTP transport.

    type MockTransport struct {
        Response    *http.Response
        RoundTripFn func(req *http.Request) (*http.Response, error)
    }
    
    func (t *MockTransport) RoundTrip(req *http.Request) (*http.Response, error) {
        return t.RoundTripFn(req)
    }
    
    func TestStore(t *testing.T) {
        mockTransport := MockTransport{
            Response: &http.Response{
                StatusCode: http.StatusOK,
                Body:       io.NopCloser(strings.NewReader(`{}`)),
                Header:     http.Header{"X-Elastic-Product": []string{"Elasticsearch"}},
            },
        }
        mockTransport.RoundTripFn = func(req *http.Request) (*http.Response, error) { return mockTransport.Response, nil }
    
        client, err := elasticsearch.NewClient(elasticsearch.Config{
            Transport: &mockTransport,
        })
        if err != nil {
            t.Fatalf("Error creating Elasticsearch client: %s", err)
        }
        // Now you can use the client for testing.
    }