使用http作为包装函数依赖项的单元测试 [英] Unit test with http as dependency for wrapper function

查看:67
本文介绍了使用http作为包装函数依赖项的单元测试的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下函数,在@poy的帮助下,我能够为其创建模拟程序以便对其进行单元测试。

I’ve the following function which after help of @poy I was able to create mock for it in order to unit test it.

现在的问题是,我ve包装函数也需要测试

The issue now that I’ve wrapper function which needs also to be tested

这是具有测试功能的原始函数

This is the original function which have working test

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请求。

This is the test which works as expected, this test use https://golang.org/pkg/net/http/httptest/ in order to mock http requests.

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)
  }

现在问题是我还有另一个函数调用了上面的函数,该函数也需要进行测试。

Now the issue is that I’ve another function which call to the above function which needs to be tested also.

这是该函数使用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。

Now when I use the test for it I got error inside the http request method since here I cannot mock the http.

Golang 中是否有任何技术可以帮助哪种情况?
我已经搜索了它,例如依赖注入,发现接口可能会帮助,但是由于这是http,所以我不确定该怎么做。

Is there any technique In Golang Which can help which this kind of scenario? I've search about it, something like dependency injection and found that maybe interface could help, but since this is http I'm not sure how to do it.

任何具有这种上下文的示例对我都非常有帮助。

Any example with this context will be very helpful to me.

推荐答案

服务对象可以具有这样的接口

Service object can have an interface like this

type Service struct {
    serviceK typeK
    serviceHttp serviceHttp // of type interface hence can be mocked
}

普通应用程序代码可以使用实际对象初始化服务。测试将包含模拟对象

Normal application code can init services with actual objects. Tests will have mocks objects

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))

}

在运行测试时,可以使用模拟实现tha初始化服务对象t返回虚拟响应。

when you are running tests, you can initialise the service object with mock Implementation that returns a dummy response.

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对其进行测试。

This is one of way testing it. Other way could be I guess where httpReq return http.ResponseWriter and you can use httptest.ResponseRecorder to test it.

这篇关于使用http作为包装函数依赖项的单元测试的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆