2017-07-16 13 views
2

私はgolangのhttpハンドラの単体テストを書いています。これについてのコードカバレッジレポートを見ると、次の問題が発生しています。要求ボディをリクエストから読み取ると、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... 
} 

はどのようにしてもnilbytesErrない場合をカバーHandlePostRequestためのテストケースを書くことができますか?

答えて

4

あなたはhttp.Requestを作成して使用することができます。この本体は、本文を読むときに意図的にエラーを返します。あなたは必ずしも全く新しい要求を必要とせず、不具合のある身体で十分です(これはio.ReadCloserです)。

io.Reader値を使用して(io.ReadCloserにラップされる)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) { 
    body, err := ioutil.ReadAll(r.Body) 
    if err != nil { 
     fmt.Printf("Error reading the body: %v\n", err) 
     return 
    } 
    defer r.Body.Close() 
    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 
+0

偉大な答えは、私が探していたものです。 return文は私の実際のコードにありますが、とにかくそれを述べてくれてありがとう、私は他人の混乱を避けるために質問に追加します。 – m90

関連する問題