In trying to set up two different web.Request
states for use in some test cases, one without any headers and one with, I run into issue:
Setup
I create fakeRequest
,fakeRequestNoHeaders
thus:
// create fake request
fakeRequest := new(web.Request)
fakeRequest.Request = httptest.NewRequest("GET",
fakeServer.URL,
nil)
fakeRequestNoHeaders := new(web.Request)
fakeRequestNoHeaders.Request = fakeRequest.Request
// give fakeRequest some headers
fakeRequest.Header.Add("Authorization", "Bearer ksjaf;oipyu7")
fakeRequest.Header.Add("Scope", "test")
Sanity Test
I expect, of course, that fakeRequest.Header != fakeRequestNoHeaders.Header
.
I write that test:
t.Run("HeadersSanityTest", func(t *testing.T) {
assert.NotEqualf(t,
fakeRequest.Header,
fakeRequestNoHeaders.Header,
"fakeRequest,fakeRequestNoHeaders share the same header state")
Result of test
It fails.
Why is this and how can I achieve what I'm trying?
UPDATE: I found the culprit:
the underlying http.Request
, returned by httptest.NewRequest
, is actually a pointer. Header
simply belongs to that Request
. The problem now reduces down to "How to deep-copy that Request
."
The issue was, indeed, not with the Header
field, but instead the Request
field, which was a pointer. (Oh no! I accidentally shallow-copied)
The Solution
I recalled, in one of my earlier tests, a method that I wrote specifically to get around this:
func makeBasicRequest() *web.Request {
baseReq := httptest.NewRequest(http.MethodPost,
"[some url here]",
nil)
req := new(web.Request)
req.Request = baseReq
return req
}
I basically just brought it into this test, and used it, hitting it once per fake request that I needed.