Potential issue with the enable/disable functionality in WebMock integration #11
Replies: 3 comments
-
@remnantkevin rhx for the thorough investigation, wasn't aware of this quirk. Did you try the patch locally, and confirmed it works? If so, I'd be happy to accept your patch, feel free to open a merge request. |
Beta Was this translation helpful? Give feedback.
-
I have tried the patch locally and have tested it works with the reproduction code shown above. I have not done any further testing / more thorough testing. I will open a MR on GitLab and we can take it from there. |
Beta Was this translation helpful? Give feedback.
-
Merge request on GitLab: https://gitlab.com/os85/httpx/-/merge_requests/247 |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
Introduction
I'm not sure if this is a bug, or if maybe I'm misunderstanding/misusing the
httpx
integration with WebMock, but I thought I would bring it up here and hopefully get clarification either way.Description
When using the
httpx
adapter for WebMock, I've run into a problem where the original/realHTTPX::Session
eventually gets 'lost', and the mocked version sticks around even after callingWebMock.disable!
. I've tried to distil the problem down to the specific logic that I think is causing the issue. See below for more details.Reproduction
An online executable copy of this reproduction is available at replit.com.
Details
At one level, the issue comes down to calling
WebMock.enable!
(A
) and thenWebMock.disable!
(B
). In the reproduction, I would expect the assertion atC
to fail, given that WebMock has been disabled (B
). However, it doesn't fail. But, if I remove lineA
(so no enable, just a disable), then the assertion atC
does fail.However, if we look at the
enable!
anddisable!
adapter code, it's not immediately clear why this would be the case:But looking at the WebMock
enable!
anddisable!
code, which calls thehttpx
adapter code, reveals a bit more:What the above WebMock code shows is that whenever
WebMock.enable!
is called, all adapters are first disabled and then enabled. And vice versa wheneverWebMock.disable!
is called.Seeing this made the problem a little clearer. The following steps happen in the reproduction code above:
WebMock.enable!
(A
)HttpxAdapter.disable!
return
s because@original_session
isnil
HttpxAdapter.enable!
HTTPX::Session
in@original_session
HTTPX::Session
to be the mocked sessionWebMock.disable!
(B
)HttpxAdapter.enable!
HTTPX::Session
in@original_session
(<-- this is where we lose a pointer to the realHTTPX::Session
)HTTPX::Session
to be the mocked sessionHttpxAdapter.disable!
HTTPX::Session
to be the@original_session
, which by this stage is the mocked session, not the real sessionSo, in some way the actual problem is that WebMock (unexpectedly, to me at least) enables before disabling and disables before enabling. Given that WebMock does this, the
httpx
adapter can account for it in a variety of ways. One of which could be to make sure@original_session
only ever stores the realHTTPX::Session
:I'm sure there are a bunch of ways to solve the problem: e.g. another way may be to early return
enable!
if@original_session
has been set (which indicates that it is already enabled); and early returndisable!
if@original_session
isnil
(which indicates that it is already disabled), and set@original_session
tonil
ifdisable!
is not early returned. But I haven't thought this through fully.These are just some suggestions. I'm sure you'll have a better idea of the best way to handle this.
I also may have totally misunderstood something here. Apologies if that is the case 🙂
Beta Was this translation helpful? Give feedback.
All reactions