web-dev-qa-db-fra.com

Comment se moquer de la méthode http.Client Do

J'essaie de trouver une solution pour écrire un test et simuler une réponse HTTP. Dans ma fonction où j'accepte l'interface:

type HttpClient interface {
    Do(req *http.Request) (*http.Response, error)
}

Je fais une requête http avec l'authentification de base

func GetOverview(client HttpClient, overview *Overview) (*Overview, error) {

    request, err := http.NewRequest("GET", fmt.Sprintf("%s:%s/api/overview", overview.Config.Url, overview.Config.Port), nil)
    if (err != nil) {
        log.Println(err)
    }
    request.SetBasicAuth(overview.Config.User, overview.Config.Password)
    resp, err := client.Do(request)

Comment puis-je me moquer de ce HttpClient? Je cherche une bibliothèque fictive, par exemple: https://github.com/h2non/gock mais il y a seulement une fausse devise pour Get and Post

Peut-être que je devrais le faire d'une manière différente. Je serai reconnaissant pour les conseils

24
quentino

Toute structure avec une méthode correspondant à la signature que vous avez dans votre interface implémentera l'interface. Par exemple, vous pouvez créer un struct ClientMock

type ClientMock struct {
}

avec la méthode

func (c *ClientMock) Do(req *http.Request) (*http.Response, error) {
    return &http.Response{}, nil
}

Vous pouvez ensuite injecter cette ClientMock struct dans votre GetOverview func. Ici est un exemple dans le terrain de jeu.

25
Gavin

Le net/http/httptest le forfait est votre meilleur ami:

// generate a test server so we can capture and inspect the request
testServer := httptest.NewServer(http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) {
    res.WriteHeader(scenario.expectedRespStatus)
    res.Write([]byte("body"))
}))
defer func() { testServer.Close() }()

req, err := http.NewRequest(http.MethodGet, testServer.URL, nil)
assert.NoError(t, err)

res, err := http.DefaultClient.Do(req)
assert.NoError(t, err)
assert.Equal(t, scenario.expectedRespStatus, res.StatusCode, "status code should match the expected response")
15
rocketspacer

Je sais que ça fait un petit bout de temps mais je viens d’écrire quelque chose pour aider avec ça récemment.

Généralement, pour simuler les requêtes HTTP, je recommande de démarrer un serveur HTTP local, car cela est facile à faire dans Go. https://golang.org/pkg/net/http/httptest/ est un moyen assez standard de le faire (voir l'exemple de code donné sous le type de serveur).

Cependant, après avoir beaucoup moqué HTTP, je voulais quelque chose qui en fasse un peu plus, comme le ferait une bonne bibliothèque fictive: définition facile des attentes, validation que toutes les demandes ont été faites, etc. J'ai généralement utilisé https: // godoc.org/github.com/stretchr/testify/mock pour se moquer et avoir voulu des fonctionnalités comme ça.

J'ai donc écrit https://github.com/dankinder/httpmock , qui combine essentiellement les deux.

3
Dan

Vous devez créer une structure avec des méthodes correspondant à l'interface. Les simulacres sont couramment utilisés à des fins de test. Par conséquent, les utilisateurs veulent pouvoir préparer les valeurs de retour des méthodes simulées. Pour cela, nous créons une structure avec les attributs func correspondant aux méthodes.

Comme votre interface est:

type HttpClient interface {
    Do(req *http.Request) (*http.Response, error)
}

Équivalent maquette:

type MockClient struct {
    DoFunc func(req *http.Request) (*http.Response, error)
}

func (m *MockClient) Do(req *http.Request) (*http.Response, error) {
    if m.DoFunc != nil {
        return m.DoFunc(req)
    }
    return &http.Response{}, nil
}

Ensuite, l'étape suivante consiste à écrire des tests. Exemple ici .

2
mwarzynski