Reputation: 3682
I've been trying for sometime to figure out how a write unit tests for handlers that use context as part of their definition.
Example
func Handler(ctx context.Context, w http.ResponseWriter, r *http.Request)
After some googling I came accross this article which made it seem as simple as
//copied right from the article
rr := httptest.NewRecorder()
// e.g. func GetUsersHandler(ctx context.Context, w http.ResponseWriter, r *http.Request)
handler := http.HandlerFunc(GetUsersHandler)
When trying to to implement the tests like this I was given the error
cannot convert Handler (type func("context".Context, http.ResponseWriter, *http.Request)) to type http.HandlerFunc
So I drove into the definition of HandleFunc
and found
// The HandlerFunc type is an adapter to allow the use of
// ordinary functions as HTTP handlers. If f is a function
// with the appropriate signature, HandlerFunc(f) is a
// Handler that calls f.
type HandlerFunc func(ResponseWriter, *Request)
// ServeHTTP calls f(w, r).
func (f HandlerFunc) ServeHTTP(w ResponseWriter, r *Request) {
f(w, r)
}
So the error makes sense... but now I'm at a lose because I need to test this Handler and it doesn't seem like I can using httptest
as the article suggested.
Is there anyway to test my handlers with the httptest
package? If not how should I go about testing?
I'm using Go1.9
UPDATE
//Just so its clear this is what I'm currently trying to do
data := url.Values{}
data.Set("event_type", "click")
data.Set("id", "1")
data.Set("email", "")
req, err := http.NewRequest("PUT", "/", bytes.NewBufferString(data.Encode()))
Expect(err).To(BeNil())
rr := httptest.NewRecorder()
// this is the problem line.
// The definition of Handler isn't (w ResponseWriter, r *Request)
// So I can't create a handler to serve my mock requests
handler := http.HandlerFunc(Handler)
handler.ServeHTTP(rr, req)
Upvotes: 1
Views: 1208
Reputation: 46413
httptest
includes everything you need to create a fake Request and ResponseWriter for testing purposes, you just need to create an appropriate fake Context
(whatever that means in your situation) and then pass all 3 to your handler function and validate what it writes to the ResponseWriter:
ctx := MakeMyContext()
w := httptest.NewRecorder()
r := httptest.NewRequest("GET", "/myroute", nil)
// headers etc
MyHandler(ctx,w,r)
// Validate status, body, headers, whatever in r
Upvotes: 1