2017-04-05 74 views
2

我试图找到一个解决方案来编写测试和模拟HTTP响应。 在我的功能,我接受接口:如何模拟http.Client做方法

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

我做HTTP GET与基地AUTH请求

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) 

我怎么能嘲笑这个HttpClient的? 我在寻找模拟库,例如:https://github.com/h2non/gock 但仅适用于获取和后

也许我应该做它用不同的方式模拟。 我将不胜感激

回答

4

任何结构与方法匹配你在你的界面中的签名将实现接口。例如,你可以创建一个结构ClientMock

type ClientMock struct { 
} 

与方法

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

然后,您可以注入该ClientMock结构到您的GetOverview FUNC。 Here是Go游乐场的一个例子。

2

您必须使用与接口匹配的方法创建结构。嘲笑通常用于测试目的,因此人们希望能够准备模拟方法的返回值。为了达到这个目的,我们用对应于方法的func属性来创建struct。

由于你的界面:

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

等效模拟:

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 
} 

然后,下一步就是编写一些测试。示例here