webmock icon indicating copy to clipboard operation
webmock copied to clipboard

including webmock/rspec in any spec file results in all specs having web disabled

Open thoraxe opened this issue 4 years ago • 4 comments

Given a file spec/services/foo_spec.rb with:

require 'rails_helper'
require 'spec_helper'
require 'webmock/rspec'

if I simply run bundle exec rspec to execute all tests, I get the following error from a completely different spec file (spec/controllers/admin/data_source_controller_spec.rb):

 2) Admin::DataSourcesController DELETE #destroy redirects to the field
     Failure/Error: body, ok=  Rack::Superfeedr.retrieve_by_topic_url(self.url, {format: 'json'})
     
     WebMock::NetConnectNotAllowedError:
       Real HTTP connections are disabled

I tried moving require webmock/rspec to both spec_helper and rails_helper immediately followed by a WebMock.disable! but that had no effect -- webmock was still enabled everywhere.

I'm assuming this is user error but I'm not understanding how I can use webmock only for certain spec files.

Also, moving the require webmock/rspec into a specific test block fixed the problem in other specs (they didn't have webmock enabled) but once the require is inside the RSpec.describe block it doesn't appear that webmock works (it didn't detect the stub I was testing for).

thoraxe avatar Jun 19 '20 23:06 thoraxe

Is it intended/expected that require webmock/rspec anywhere (in any spec) results in it being loaded everywhere? I am thinking this is an artifact of the way that rspec loads all tests/specs ahead of time? This is probably not a webmock issue, I don't think?

thoraxe avatar Jul 28 '20 12:07 thoraxe

@thoraxe yes, it's intended that require webmock/rspec results with WebMock being loaded everywhere.

If you take a look at webmock/rspec source, it simply loads WebMock, enables it (globally) and adds some callback to rspec.

WebMock interecepts the requests on http client level. It doesn't know where the requests came from. Whether they came from a code invoked inside rspec test or from server code that was loaded as well and there is no way to control that.

I suggest you invoke disable_net_connect! and add allow option with the urls/hosts/ports that you don't wan't to be intercepted by WebMock.

bblimke avatar Sep 11 '20 06:09 bblimke

Hello, I have a similar problem but for some reason the suggested solution is not working for me, I still get WebMock::NetConnectNotAllowedError for the allowed urls.

I tried putting the line

allowed_sites = [
  "https://chromedriver.storage.googleapis.com",
  "https://github.com/mozilla/geckodriver/releases",
  "https://selenium-release.storage.googleapis.com",
   "https://developer.microsoft.com/en-us/microsoft-edge/tools/webdriver"
]
WebMock.disable_net_connect!(allow_localhost: true, allow: allowed_sites)
  1. directly in the RSpec.configure block in rails_helper.rb
  2. in a before(:each) block inside the Rspec.configure one
  3. directly inside the test where I need the stub

In all cases the requests to the above url are blocked. What is most puzzling is that I have the same setup on a different project where it is working fine (i.e., allowed urls are allowed as expected). Any hint on how to debug where I'm going wrong?

cecilian avatar Oct 26 '21 14:10 cecilian

@cecilian Is the http request made from the code invoked inside the test? If yes, then perhaps there is some code that again disables the connections after the setup and before the request is invoked?

The following code works find:

WebMock.enable!

allowed_sites = [
  "https://chromedriver.storage.googleapis.com",
  "https://github.com/mozilla/geckodriver/releases",
  "https://selenium-release.storage.googleapis.com",
   "https://developer.microsoft.com/en-us/microsoft-edge/tools/webdriver"
]
WebMock.disable_net_connect!(allow_localhost: true, allow: allowed_sites)

Net::HTTP.get(URI.parse("https://chromedriver.storage.googleapis.com"))

bblimke avatar Nov 03 '21 10:11 bblimke