Geo*_*man 4 json unit-testing go
我正在尝试测试net/http用于发出请求的方法。具体来说,我要实现的目标是注入一个http.Client以某个JSON主体响应的模拟
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 }
Run Code Online (Sandbox Code Playgroud)
我确实知道的Body是类型io.ReadCloser接口。麻烦的是,我一生无法找到在模拟身体反应中实施该方法的方法。
示例如下发现这里至今只展示返回空白&http.Response{}
小智 6
In your test file (my_test.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")
}
Run Code Online (Sandbox Code Playgroud)
In your implementation (main.go):
package main
import (
"net/http"
)
func main() {
myFunction(&http.Client{})
}
Run Code Online (Sandbox Code Playgroud)
虽然使用来模拟整个请求周期可能更有用httptest.Server,但是您可以使用ioutil.NopCloser它在任何阅读器周围创建更紧密的联系:
Body: ioutil.NopCloser(bytes.NewReader(body))
Run Code Online (Sandbox Code Playgroud)
如果您想要一个空的正文,请提供没有内容的阅读器。
Body: ioutil.NopCloser(bytes.NewReader(nil))
Run Code Online (Sandbox Code Playgroud)