I'm searching for an easy way to test that http.Response.Body.Close() was called.
I already tried this by counting the number of open connections to the server (https://golang.org/src/net/http/serve_test.go - countCloseListener), but it seems that it only is testable on the client side, via rewriting the Roundtripper.
So the following example works, but I'm wondering whether there is an easier way for such a common task...
package closing
import "net/http"
type MyClient struct {
Client http.Client
}
func (c *MyClient) Closing() (err error) {
res, err := c.Client.Get("http://localhost")
defer res.Body.Close()
return
}
func (c *MyClient) NotClosing() (err error) {
_, err = c.Client.Get("http://localhost")
return
}
https://github.com/elgohr/golang-test-body-close/blob/master/performsHttpRequest.go
package closing_test
import (
"github.com/elgohr/closing"
"io"
"io/ioutil"
"net/http"
"strings"
"testing"
)
func TestShouldBeClosedWhenClosed(t *testing.T) {
tripper := NewFakeRoundTripper()
cl := closing.MyClient{
Client: http.Client{
Transport: tripper,
},
}
if err := cl.Closing(); err != nil {
t.Error(err)
}
if !tripper.Body.Closed {
t.Error("Should be closed, but wasn't")
}
}
func TestShouldBeOpenWhenNotClosed(t *testing.T) {
tripper := NewFakeRoundTripper()
cl := closing.MyClient{
Client: http.Client{
Transport: tripper,
},
}
if err := cl.NotClosing(); err != nil {
t.Error(err)
}
if tripper.Body.Closed {
t.Error("Should be open, but wasn't")
}
}
func NewFakeRoundTripper() *FakeRoundTripper {
return &FakeRoundTripper{
Body: &FakeReadCloser{
ReadCloser: ioutil.NopCloser(strings.NewReader("content")),
},
}
}
type FakeRoundTripper struct {
Body *FakeReadCloser
}
func (r *FakeRoundTripper) RoundTrip(*http.Request) (*http.Response, error) {
return &http.Response{
Body: r.Body,
}, nil
}
type FakeReadCloser struct {
io.ReadCloser
Closed bool
}
func (r *FakeReadCloser) Close() error {
r.Closed = true
return r.ReadCloser.Close()
}
https://github.com/elgohr/golang-test-body-close/blob/master/performsHttpRequest_test.go