webmock icon indicating copy to clipboard operation
webmock copied to clipboard

`enable_net_connent!()` with a block

Open yegor256 opened this issue 1 month ago • 3 comments

Now I have to do this:

WebMock.enable_net_connect!
begin
  # go to google.com
ensure
  WebMock.disable_net_connect!
end

Would be more convenient to do this:

WebMock.enable_net_connect! do 
  # go to google.com
end

yegor256 avatar Oct 29 '25 05:10 yegor256

@yegor256 I like this idea. It would definitely be more convenient!

However, it's not as straightforward as it seems.

Both disable_net_connect and enable_net_connect take options that modify WebMock's global state. With a block form, we'd need to answer some tricky questions:

  • What state should be restored after exiting the block?
  • What options should be applied when restoring the previous state?
  • If options differ inside vs outside the block, do we merge them or replace them?

These edge cases make the implementation more complex than it first appears. Open to ideas on how to handle this elegantly. What do you think?

bblimke avatar Oct 29 '25 23:10 bblimke

@bblimke maybe we can remember the options when we enter the block and then restore them on exit, ignoring any changes possibly made inside the block or globally? This is the behavior I would most probably expect as a user.

yegor256 avatar Oct 30 '25 03:10 yegor256

So I think I've gotten here from seeking the same underlying problem that @yegor256 is working on, but I'm thinking that using disable_net_connect and enable_net_connect is not the right solution - in my case, I'm wanting to block web requests except in one specific test I allow them to test a download of a binary from a GitHub release.

What if instead we could have something like:

stub_request(:any, "www.example.com").to_call_original

I expect there could be a few different ways that could be archived since ultimately webmock controls if a request can be made - so while ideally it would be best if the underlying client could handle the whole request, an alternative could be that webmock effectively makes it with its own client and passes that back, and you could expose it like that too if that was an easier path:

allow(my_instance_double).to receive(:fetch_data) do 
  WebMock.make_actual_web_request("www.example.com")
end

G-Rath avatar Nov 04 '25 00:11 G-Rath