Как ввести URL-адрес для httptest.server в Голанге?
Для предложения
resp, err := client.Get(fmt.Sprintf("https://www.xxxxx/day?time=%s", time))
Если я хочу смоделировать ответ на этот client.Get() в модульном тесте, я должен использовать httptest.server, но как я могу привязать URL ( https://www.xxxxx/day?time=%s) к URL httptest.server? так что когда я вызываю client.Get(), он может вернуть ответ, который я установил ранее. По какой-то причине я не могу издеваться над клиентом здесь.
2 ответа
Как это
func NewTestServerWithURL(URL string, handler http.Handler) (*httptest.Server, error) {
ts := httptest.NewUnstartedServer(handler)
if URL != "" {
l, err := net.Listen("tcp", URL)
if err != nil {
return nil, err
}
ts.Listener.Close()
ts.Listener = l
}
ts.Start()
return ts, nil
}
Обычно нет. Вы берете базовый URL-адрес с сервера и передаете его клиенту:
package main
import (
"fmt"
"net/http"
"net/http/httptest"
"testing"
"time"
)
func TestClient(t *testing.T) {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// Verify request, send mock response, etc.
}))
defer server.Close()
var client *http.Client
var time time.Time
baseURL := server.URL // Something like "http://127.0.0.1:53791"
resp, err := client.Get(fmt.Sprintf(baseURL+"/day?time=%s", time))
if err != nil {
t.Fatal(err)
}
// Verify response body if applicable
resp.Body.Close()
}
Http.Client - это структура, а не интерфейс, который, как вы уже видели, делает насмешку сложной. Альтернативный способ насмешки - передача внешних зависимостей, в которых нуждается подпрограмма, поэтому вместо непосредственного использования client.Get вы используете clientGet - указатель на функцию, передаваемый в подпрограмму.
Из модульного теста вы можете создать:
mockClientGet(c *http.client, url string) (resp *http.Response, err error) {
// add the test code to return what you want it to.
}
Тогда в вашем основном коде используйте:
resp, err := clientGet(client, fmt.Sprintf("https://www.xxxxx/day?time=%s", time))
При обычном вызове процедуры используйте указатель на функцию http.Client.Get, а для теста передайте указатель на макет. Это не идеальный вариант, но я не видел более приятного способа обхода внешних вызовов, не связанных с интерфейсом, - и учитывая его внешнюю зависимость, вводить его извне - неплохая вещь.