Closed alvii147 closed 3 weeks ago
Hi,
You are right, we always should use Cleanup
instead of defer
but this method appeared in 1.14 and httpmock is announced to run on 1.13, that's why the docs still use defer
instead of Cleanup
.
I plan to remove this restriction targeting at least 1.16 (3.5 year old), and use new features in internal code. During this switch, httpmock.Activate()
signature could be changed to httpmock.Activate(...testing.TB)
to automatically call Cleanup
on first arg if passed without breaking existing code.
@maxatome, ahh that makes sense, thanks for the clarification. If the switch from httpmock.Activate()
to httpmock.Activate(...testing.TB)
is planned soon, I'm happy to help out on that too!
Hi there,
I just replaced the
defer
statements witht.Cleanup
in the README, as it's generally not a good idea to usedefer
in tests. Lemme explain why.Consider this test:
I'm using the httpstatus service as mock URLs to send requests to. Sending requests to
https://mock.httpstatus.io/{status_code}
always returns a response with the specified status code.The test above is using test tables to send
GET
requests to the following two endpoints:https://mock.httpstatus.io/400
https://mock.httpstatus.io/404
Normally
https://mock.httpstatus.io
will respond with400
and404
respectively, but the test is mocking both to respond with200
. If we run this test, it does exactly that, and passes with no issues:The problem shows up when we add the
t.Parallel()
directive to make the two test cases run in parallel:When we run this, we get:
The logged output is telling us that
https://mock.httpstatus.io
actually responded with400
and404
respectively, which means we actually sent a request tohttps://mock.httpstatus.io
, andhttpmock
failed to intercept it. But why?The answer is the
defer
statement actually runs before the individual test cases when the test cases are parallelized. This is an important feature of Go's testing library, you can read more about it here.For this purpose exactly, Go's testing library offers the
t.Cleanup()
. Any function passed intot.Cleanup()
will only execute after all sub tests have executed and returned. If we replace thedefer
statement witht.Cleanup()
, this issue no longer persists, and we are able to run tests in parallel properly: