我正在用golang编写HTTP处理程序的单元测试。在查看代码覆盖率报告时,我遇到了以下问题:从请求中读取请求正文时,ioutil.ReadAll可能会返回我需要处理的错误。但是,当我为我的处理程序编写单元测试时,我不知道如何以触发该错误的方式将请求发送到我的处理程序(内容的结尾过早似乎不会产生这样的错误,但是会在解体身体)。这就是我想要做的:
ioutil.ReadAll
package demo import ( "bytes" "io/ioutil" "net/http" "net/http/httptest" "testing" ) func HandlePostRequest(w http.ResponseWriter, r *http.Request) { body, bytesErr := ioutil.ReadAll(r.Body) if bytesErr != nil { // intricate logic goes here, how can i test it? http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest) return } defer r.Body.Close() // continue... } func TestHandlePostRequest(t *testing.T) { ts := httptest.NewServer(http.HandlerFunc(HandlePostRequest)) data, _ := ioutil.ReadFile("testdata/fixture.json") res, err := http.Post(ts.URL, "application/json", bytes.NewReader(data)) // continue... }
我HandlePostRequest该如何为bytesErr不存在的情况编写测试用例nil?
HandlePostRequest
bytesErr
nil
您可以创建和使用http.Request伪造的伪造品,在读取其主体时会故意返回错误。您不一定需要一个全新的请求,有缺陷的主体就足够了(这是一个io.ReadCloser)。
http.Request
io.ReadCloser
使用此httptest.NewRequest()函数可以实现最简单的方法,在该函数中您可以传递io.Reader将用作io.ReadCloser请求正文的值(包装为)。
httptest.NewRequest()
io.Reader
这是一个示例io.Reader,尝试从中读取错误时故意返回错误:
type errReader int func (errReader) Read(p []byte) (n int, err error) { return 0, errors.New("test error") }
涵盖您的错误情况的示例:
func HandlePostRequest(w http.ResponseWriter, r *http.Request) { defer r.Body.Close() body, err := ioutil.ReadAll(r.Body) if err != nil { fmt.Printf("Error reading the body: %v\n", err) return } fmt.Printf("No error, body: %s\n", body) } func main() { testRequest := httptest.NewRequest(http.MethodPost, "/something", errReader(0)) HandlePostRequest(nil, testRequest) }
输出(在Go Playground上尝试):
Error reading the body: test error