Как я могу извлечь этот API в интерфейс, чтобы я мог издеваться над ним в моих тестах? - PullRequest
0 голосов
/ 03 ноября 2018

Так что в настоящее время у меня есть обработчик http, который выглядит следующим образом:

type App struct {

}
func (a *App) someHandler(w http.ResponseWriter, r *http.Request) {
        var api = slack.New("TOKEN")
        users = api.GetUsers()
}

Я хочу создать интерфейс для этого вызова slack.New ("..."), чтобы в моих тестах API не делал сетевые запросы на провисание.

Как я могу издеваться над этим Новым звонком?

Вызов New ("TOKEN") возвращает * клиента, см. Ссылку ниже:

func New(token string, options ...Option) *Client {
    s := &Client{
        token:      token,
        httpclient: &http.Client{},
        log:        log.New(os.Stderr, "nlopes/slack", log.LstdFlags|log.Lshortfile),
    }

    for _, opt := range options {
        opt(s)
    }

    return s
}

https://github.com/nlopes/slack/blob/0f8db5050731c50359e319cf253af5b9997a2b1e/slack.go#L84

Я не слишком часто использовал интерфейсы, поэтому не уверен, что это нельзя вставить в интерфейс, поскольку вызов New похож на конструктор?

1 Ответ

0 голосов
/ 03 ноября 2018

Вы не можете смоделировать сам вызов slack.New, вместо этого вам нужно создать макет, который будет вести себя как этот api объект. Для этого поместите api в структуру App, но в качестве интерфейса:

type SlackClient interface {
    GetUsers() []string
}

type App struct {
    api SlackClient
}

func (a *App) someHandler(w http.ResponseWriter, r *http.Request) { 
    users = a.api.GetUsers() 
}

Затем вам нужно переместить вызов на slack.New во все, что создает App (например, вашу основную функцию или функцию конструктора NewApp):

app = App{api: slack.New("TOKEN")}

Клиент, который он возвращает, имеет метод GetUsers, поэтому он будет соответствовать интерфейсу, который мы определили.

Затем тест делает нечто похожее с макетом:

type mockSlackClient struct {

}

func (m *mockSlackClient) GetUsers() []string {
    return nil
}

func TestSomeHandler(t *testing.T) {
    appToTest := App{api: &mockSlackClient{})

    appToTest.someHandler(httptest.NewRecorder(), nil)
}

Опять же, поскольку у *mockSlackClient есть метод GetUsers, он удовлетворит интерфейс, поэтому вы сможете использовать его на App.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...