如何模拟返回JSON响应的http.Client

时间:2017-11-22 13:43:50

标签: json unit-testing go

我正在尝试测试使用net/http发出请求的方法。具体来说,我想要实现的是注入一个响应某个JSON主体的模拟http.Client

type clientMock struct{}

func (c *clientMock) Do(req *http.Request) (*http.Response, error) {
  json := struct {
    AccessToken string `json:"access_token`
    Scope       string `json:"scope"`
  }{
    AccessToken: "123457678",
    Scope:       "read, write",
  }
  body := json.Marshal(json)
  res := &http.Response {
    StatusCode: http.StatusOK,
    Body:       // I haven't got a clue what to put here
  }
  return res
}

func TestRequest(t *testing.T) { //tests here }

我知道Body属于io.ReadCloser类型接口。麻烦是我不能为我的生活找到一种方法来实现它在模拟身体的反应。

到目前为止找到的示例here仅显示返回空白&http.Response{}

3 个答案:

答案 0 :(得分:4)

虽然使用httptest.Server模拟完整的请求周期可能更有用,但您可以使用ioutil.NopCloser创建更靠近任何读者的距离:

#define REGISTER_1 ??? /* Return value with 
GET(REGISTER_1) if not accessed with an assignment like REGISTER_1 = ... */

如果你想要一个空体,只需提供一个没有内容的读者。

Body: ioutil.NopCloser(bytes.NewReader(body))

答案 1 :(得分:1)

在您的测试文件(my_test.go)中:

-L

在您的实施中(main.go):

type MyJSON struct {
        Id          string
        Age         int
    }

    // Interface which is the same as httpClient because it implements "Do" method.
    type ClientMock struct {
    }

    func (c *ClientMock) Do(req *http.Request) (*http.Response, error) {

    mockedRes := MyJSON {"1", 3}

    // Marshal a JSON-encoded version of mockedRes
    b, err := json.Marshal(mockedRes)

        if err != nil {
            log.Panic("Error reading a mockedRes from mocked client", err)
        }

    return &http.Response{Body: ioutil.NopCloser(bytes.NewBuffer(b))}, nil
    }

// your test which will use the mocked response
func TestMyFunction(t *testing.T) {

    mock := &ClientMock{}
    actualResult := myFunction(mock)
    assert.NotEmpty(t, actualResult, "myFunction should have at least 1 result")

}

答案 2 :(得分:0)

我知道它已经有一段时间了,但我最近写了一些东西来帮助解决这个问题。

和JimB一样,我建议在本地启动一个真正的HTTP服务器,因为在Go中这很容易用https://golang.org/pkg/net/http/httptest/

然而,做了很多HTTP模拟,我想要更多的东西,比如一个好的模拟库:返回特定数据,轻松设置期望,验证所有请求都是等等。我通常使用{ {3}}用于模拟和想要的功能。

所以我写了https://godoc.org/github.com/stretchr/testify/mock,基本上将两者结合起来。如果你只想要一个接受JSON并吐出JSON的模拟器,它可能是一种更容易的方法。