我正在尝试测试使用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{}
答案 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的模拟器,它可能是一种更容易的方法。