如何在读取请求正文时测试错误? [英] How do I test an error on reading from a request body?

查看:87
本文介绍了如何在读取请求正文时测试错误?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在用golang编写针对HTTP处理程序的单元测试。在查看此内容的代码覆盖率报告时,我遇到以下问题:从请求中读取请求正文时, ioutil.ReadAll 可能会返回我需要处理的错误。但是,当我为我的处理程序编写单元测试时,我不知道如何以触发该错误的方式将请求发送到我的处理程序(内容的结尾过早似乎不会产生这样的错误,但是会在解开身体)。这就是我要尝试做的:

I'm writing unit tests for http Handlers in golang. When looking at code coverage reports of this I am running into the following issue: When reading the request body from a request, ioutil.ReadAll might return an error that I need to handle. Yet, when I write unit tests for my handler I do not know how to send a request to my handler in a way that it will trigger such an error (premature end of content seems not to generate such an error but will generate an error on unmarshaling the body). This is what I am trying to do:

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 的情况吗?

How can I write a test case for HandlePostRequest that also covers the case of bytesErr not being nil?

推荐答案

您可以创建并使用 http.Request 由您伪造,在读取其主体时会故意返回错误。您不一定需要一个全新的请求,一个错误的正文就足够了(这是一个 io.ReadCloser )。

You may create and use an http.Request forged by you, which deliberately returns an error when reading its body. You don't necessarily need a whole new request, a faulty body is enough (which is an io.ReadCloser).

使用 httptest.NewRequest() 函数,您可以在其中传递 io.Reader 值(将其包装为是 io.ReadCloser )作为请求正文。

Simplest achieved by using the httptest.NewRequest() function where you can pass an io.Reader value which will be used (wrapped to be an io.ReadCloser) as the request body.

下面是一个示例 io。 Reader 尝试从中读取时故意返回错误:

Here's an example io.Reader which deliberately returns an error when attempting to read from it:

type errReader int

func (errReader) Read(p []byte) (n int, err error) {
    return 0, errors.New("test error")
}

将介绍您的错误情况的示例:

Example that will cover your error case:

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

输出(在去游乐场):

Error reading the body: test error

请参阅相关问题,是否需要模拟从a读取的错误响应正文(不是来自请求正文):如何在读取响应正文时出现强制错误

See related question if you would need to simulate error reading from a response body (not from a request body): How to force error on reading response body

这篇关于如何在读取请求正文时测试错误?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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