Как выполнить модульный тест go кода, взаимодействующего с Elasticsearch - PullRequest
0 голосов
/ 10 марта 2020

У меня есть приложение, которое определяет type Client struct {}, которое взаимодействует с другими клиентами в моем коде, которые общаются с такими сервисами, как github ,asticsearch et c.

Теперь у меня есть следующий код ES в одном из моих пакетов

type SinkService interface {
    Write(context, index, mapping, doc)
}

type ESSink struct {
   client *elastic.Client
}

func NewESSink() *ESSink {}

 // checks if the index exists and writes the doc
func (s *ESSink) Write(context, index, mapping, doc) {}

Я использую этот метод в своем главном клиенте, который запускает все приложение, как это c.es.Write(...). Теперь, если я хочу написать client_test.go, я могу просто сделать mockESSink и использовать его с некоторым заглушкой, но это не будет охватывать строки, написанные в моем коде ES.

Как выполнить модульное тестирование моего кода ES ? Мой ESSink использует elastic.Client. Как мне это посмеяться?

Я хотел бы встроить некоторый фиктивный клиент ES, который дает мне ответы на заглушки, и я смогу протестировать свой метод ESSink.Write таким образом.

1 Ответ

1 голос
/ 13 марта 2020

Исходя из вашего вопроса, я предполагаю, что вы используете github.com/olivere/elastic, и вы хотите иметь возможность проводить тестирование с использованием тупых http ответов. Когда я впервые прочитал этот вопрос, я также никогда не писал Go тестовый код, использующий клиент ES. Итак, в дополнение к ответу на этот вопрос, я также делюсь тем, как я узнаю ответ от крестников.

Во-первых, мы видим, что elastic.NewClient принимает функции опций клиента. Поэтому я проверил, какие функции клиентских опций предоставляет библиотека. Оказывается, библиотека предоставляет elastic.SetHttpClient, который принимает elastic.Doer. Doer - это интерфейс, который http.Client может реализовать. Отсюда ответ становится понятным.

Итак, вам необходимо:

  1. Изменить func NewESSink() для принятия http Client или elasti c Client.
  2. Записать заглушку http Client (реализует elastic.Doer).

ESSink

type ESSink struct {
    client *elastic.Client
}

func NewESSink(client *elastic.Client) *ESSink {
    return &ESSink{client: client}
}

Заглушка HttpClient

package stubs

import "net/http"

type HTTPClient struct {
    Response *http.Response
    Error    error
}

func (c *HTTPClient) Do(*http.Request) (*http.Response, error) {
    return c.Response, c.Error
}

Ваш код тестирования

func TestWrite(t *testing.T) {
    // set the body and error according to your test case
    stubHttpClient := stubs.HTTPClient{ 
        Response: &http.Response{Body: ...},
        Error: ...,
    }

    elasticClient := elastic.NewClient(elastic.SetHttpClient(stubHttpClient))
    esSink := NewESSink(elasticClient)
    esSink.Write(...)
}

В вашем рабочем коде вы можете использовать http.Client{} при настройке клиента ES http.

...