onsi / gomega

Ginkgo's Preferred Matcher Library
http://onsi.github.io/gomega/
MIT License
2.17k stars 282 forks source link

Helper to create a RoundTripper for ghttp.Server #769

Closed Smirl closed 3 months ago

Smirl commented 3 months ago

Summary

Currently we can use server := ghttp.NewServer() to create a test server, then use server.URL() or server.Addr() to point our clients to the test server.

In some situations code is not written in such a way where the URL can passed to a function, or perhaps paths should be conserved. It is common for libraries to be able to configure a http.Client, and therefore a http.Transport. The interface RoundTripper allows us to take a request, modify it in someway, and return the response/error

Proposal

Add a new method to ghttp.Server which returns a RoundTripper. This can then be used to build http clients, or wrap existing transports (i.e. in req's WrapRoundTrip link).

Because we need to send a real request to our test server, we still require an actual transport. Therefore, the method takes a RoundTripper. If this is nil then we can use http.DefaultTransport.

For example:

func (s *Server) RoundTripper(rt http.RoundTripper) http.RoundTripper {
    if rt == nil {
        rt = http.DefaultTransport
    }
    return RoundTripperFunc(func(r *http.Request) (*http.Response, error) {
        r.URL.Scheme = "http"
        r.URL.Host = s.Addr()
        return rt.RoundTrip(r)
    })
}

Where the helper RoundTripperFunc is as such. Note there is an open issue to add this to net/http in https://github.com/golang/go/issues/38479.

type RoundTripperFunc func (*http.Request) (*http.Response, error)

func (fn RoundTripperFunc) RoundTrip(r *http.Request) (*http.Response, error) {
    return fn(r)
}

Example usage

var _ = Describe("A Sprockets Client", func() {
    var server *ghttp.Server
    var client *SprocketClient
    BeforeEach(func() {
        server = ghttp.NewServer()
        httpClient := http.Client{Transport: server.RoundTripper(nil)}
        client = NewSprocketClient(httpClient, "skywalker", "tk427")
    })

    AfterEach(func() {
        server.Close()
    })
})
onsi commented 3 months ago

heyo this make sense to me. are you up for submitting a PR that includes an update to the long-form docs? thanks!

Smirl commented 3 months ago

@onsi Thanks for the fast response. I have raised #770. Let me know what you think.