Testing Setting HTTP Cookies in Go
Posted on Thu 04 February 2016 in Golang
I found myself writing code that drops HTTP Cookies on a HTTP ResponseWriter and had trouble figuring out how to test it:
type Preferences struct {
Colour string
}
func SetPreferencesCookie(w http.ResponseWriter, prefs *Preferences) error {
data, err := json.Marshal(prefs)
if err != nil {
return err
}
http.SetCookie(w, &http.Cookie{
Name: "test",
Value: base64.StdEncoding.EncodeToString(data),
})
return nil
}
The answer comes in the form of copying the Headers from an http.Recorder
into an http.Response
object.
func TestSetPreferencesCookie(t *testing.T) {
// Create a new HTTP Recorder (implements http.ResponseWriter)
recorder := httptest.NewRecorder()
// Drop a cookie on the recorder.
SetPreferencesCookie(recorder, &Preferences{ Colour: "Blue" })
// Copy the Cookie over to a new Request
request := &http.Request{Header: http.Header{"Cookie": recorder.HeaderMap["Set-Cookie"]}}
// Extract the dropped cookie from the request.
cookie, err := request.Cookie("test")
require.NoError(t, err, "Failed to read 'test' Cookie": %v, err)
// Decode the cookie
data, err := base64.StdEncoding.DecodeString(cookie.Value)
require.NoError(t, err, "Failed to Base64 decode 'test' Cookie: %v", err)
// Unmarshal contents back into a Preferences struct
var prefs *Preferences
err = json.Unmarshal(data, &prefs)
require.NoError(t, err, "Failed to parse 'test' Cookie JSON: %v", err)
// Check the contents.
require.Equal(t, "Blue", prefs.Colour)
}
Have a play with this code on the Go Playground: http://play.golang.org/p/r7aGdX9YEn.