我有以下功能,在@poy的帮助下,我能够为其创建模拟以便对其进行单元测试。
现在,我具有包装器功能的问题也需要测试
这是经过工作测试的 原始 功能
func httpReq(cc []string, method string, url string) ([]byte, error) { httpClient := http.Client{} req, err := http.NewRequest(method, url, nil) if err != nil { return nil, errors.Wrap(err, "failed to execute http request") } //Here we are passing user and password req.SetBasicAuth(cc[1], cc[2]) res, err := httpClient.Do(req) if err != nil { fmt.error(err) } val, err := ioutil.ReadAll(res.Body) if err != nil { fmt.error(err) } defer res.Body.Close() return val, nil }
这是按预期工作的测试,该测试使用 https://golang.org/pkg/net/http/httptest/来模拟http请求。
func Test_httpReq(t *testing.T){ expectedValue = "some-value" server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request){ u,p,ok := r.BasicAuth() if !ok || u != "fakeuser" || p != "fakepassword" { t.Fatal("wrong auth") } w.Write([]byte(expectedValue)) }) val, err := httpReq( []string{"fakeuser", "fakepassword"}, http.MethodPost, server.URL, ) if err != nil{ t.Fatal(err) } if val != expectedValue { t.Fatalf("expected %q to equal %q", val, expectedValue) }
现在的问题是,我还有另一个函数 需要调用上述函数 ,还需要对其进行测试。
这是使用httpReq的函数,我也需要为其创建测试
func (c *Service) invoke(Connection Connection, args []string) { service, err := c.getService(Connection, args) serviceC, err := c.getServiceK(service, []string{"url", “user”, “id”}) c := strings.Fields(serviceC) //—————Here we are using the http function again val, err := httpReq(c[1], c[1],”post”, c[0]) if err != nil { fmt.println(err) } fmt.Print(string(val)) }
现在,当我使用测试进行测试时, http请求方法 内部出现错误,因为在这里我无法模拟http。
有没有technique在Golang这可以帮助这种哪种情况呢?我已经进行了搜索,例如依赖注入,发现 接口可能会有所帮助 ,但是由于这是http,所以我不确定如何执行。
technique
Golang
在这种情况下的任何示例对我都会非常有帮助。
服务对象可以具有这样的接口
type Service struct { serviceK typeK serviceHttp serviceHttp // of type interface hence can be mocked }
普通应用程序代码可以使用实际对象初始化服务。测试将包含模拟对象
type Req struct { } type Resp struct { } type ServiceHttp interface{ HttpReq(params Req)(Resp, error) } type Implementation struct { } func (i *Implementation)HttpReq(params Req)(Resp, error){ // buid http request } func (c *Service) invoke(Connection Connection, args []string) { service, err := c.getService(Connection, args) serviceC, err := c.getServiceK(service, []string{"url", “user”, “id”}) c := strings.Fields(serviceC) serviceImp := c.GetServiceImp() // init params with the required fields val, err := c.HttpReq(params) if err != nil { fmt.println(err) } fmt.Print(string(val)) }
运行测试时,可以使用模拟实现初始化服务对象,该实现返回虚拟响应。
type MockImplementation struct { } func (i *MockImplementation)HttpReq(Resp, error){ // return mock response } func TestMain(){ services := { serviceHttp:MockImplementation{}, serviceK: typeK{}, // initialise this } }
这是测试它的方法之一。其他方法可能是我猜httpReq返回http.ResponseWriter的地方,您可以使用httptest.ResponseRecorder对其进行测试。