Is your feature request related to a problem? Please describe.
Hey! I was using apitest to assert some response headers and thought the messaging in case of errors could be improved a little and would like to get your opinions.
Taking this simple test as an example with an assertion on the response Location
header
func TestApiTest_Redirect(t *testing.T) {
apitest.New().
Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
http.Redirect(w, r, "/foo", http.StatusSeeOther)
})).
Get("/").
Expect(t).
Status(http.StatusSeeOther).
Header("Location", "/bar").
End()
}
The test result shows
=== RUN TestApiTest_Redirect
TestApiTest_Redirect: /home/user/workspace/apitest/apitest.go:967: could not match header=Location
--- FAIL: TestApiTest_Redirect (0.00s)
The error message details could not match header=Location
and the header is present in the response, but the value is incorrect (/bar
vs /foo
)
Now let's take an example where the header is not present at all
func TestApiTest_Redirect(t *testing.T) {
apitest.New().
Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
http.Redirect(w, r, "/foo", http.StatusSeeOther)
})).
Get("/").
Expect(t).
Status(http.StatusSeeOther).
Header("My-Header", "example").
End()
}
The test results show
=== RUN TestApiTest_Redirect
TestApiTest_Redirect: /home/user/workspace/apitest/apitest.go:967: could not match header=My-Header
--- FAIL: TestApiTest_Redirect (0.00s)
The error message details could not match header=My-Header
is the same as the previous test, but this time the header is not present at all.
The above tests are quite simple, but if you think of cases with more complex http handlers there is no way from the error message to understand if the header is not present at all or if it's present but the value is incorrect.
I've noticed that Cookie()
takes a different approach to assertion error messages like below
func TestApiTest_Redirect2(t *testing.T) {
apitest.New().
Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
http.SetCookie(w, &http.Cookie{
Name: "ABC",
Value: "12345",
})
http.Redirect(w, r, "/newurl", http.StatusSeeOther)
})).
Get("/").
Expect(t).
Status(http.StatusSeeOther).
Cookie("ABC", "AAA").
Cookie("DDD", "AAA").
End()
}
which gives a clear feedback of which cookie is missing or which values are incorrect
=== RUN TestApiTest_Redirect2
TestApiTest_Redirect2: /home/user/workspace/apitest/assert.go:29:
Error Trace: assert.go:29
apitest.go:927
apitest.go:750
apitest.go:556
apitest_test.go:1073
Error: Not equal:
expected: 0
actual : 1
Test: TestApiTest_Redirect2
Messages: Mismatched field Value. Expected AAA but received 12345
TestApiTest_Redirect2: /home/user/workspace/apitest/assert.go:29:
Error Trace: assert.go:29
apitest.go:926
apitest.go:750
apitest.go:556
apitest_test.go:1073
Error: Not equal:
expected: true
actual : false
Test: TestApiTest_Redirect2
Messages: ExpectedCookie not found - DDD
--- FAIL: TestApiTest_Redirect2 (0.00s)
Describe the solution you'd like
I think it would be nice for the library to give better feedback when asserting response headers using Header()
or Headers()
similar to the one when Cookie()
is used.
Something like
TestApiTest_Redirect: /home/user/workspace/apitest/assert.go:29:
Error Trace: assert.go:29
apitest.go:974
apitest.go:749
apitest.go:556
apitest_test.go:1062
Error: Not equal:
expected: 0
actual : 1
Test: TestApiTest_Redirect
Messages: Mismatched values for header Location. Expected /bar but received /foo
TestApiTest_Redirect: /home/user/workspace/apitest/assert.go:29:
Error Trace: assert.go:29
apitest.go:972
apitest.go:749
apitest.go:556
apitest_test.go:1062
Error: Not equal:
expected: true
actual : false
Test: TestApiTest_Redirect
Messages: expected header My-Header not present in response
Describe alternatives you've considered
One could call HeaderPresent("Location")
before calling Header()
, but I think it's more convenient sometimes to just use Header()/Headers()
particularly if you're asserting the value of the header.
And even in you were to use HeaderPresent("Location")
beforehand you still wouldn't get the information of the mismatched values, ex. Expected /bar but received /foo
Additional context
Let me know if this something you think is worth improving. Happy to pick it up if needed!