webmock icon indicating copy to clipboard operation
webmock copied to clipboard

Allow global stubbing (e.g. before :suite)

Open collimarco opened this issue 10 years ago • 12 comments

In Rspec this works:

RSpec.configure do |config|
  config.before :each do
     WebMock.stub_request(...)
  end
end

However this doesn't work:

RSpec.configure do |config|
  config.before :suite do
     WebMock.stub_request(...)
  end
end

I think it would be useful to stub something globally only once in a before :suite.

collimarco avatar May 28 '15 14:05 collimarco

Because it calls WebMock.reset! in after(:each) block, if you require 'webmock/rspec'. See https://github.com/bblimke/webmock/blob/master/lib/webmock/rspec.rb#L29.

VincentZhao avatar Jun 28 '15 05:06 VincentZhao

+1

kalinchuk avatar Dec 23 '16 19:12 kalinchuk

@VincentZhao do you know why is necessary to reset the mocks after every test (as the source code does)?

giovannibenussi avatar Sep 13 '17 13:09 giovannibenussi

@giovannibenussi because we want to have a clean state when entering a new example.

bblimke avatar Sep 13 '17 20:09 bblimke

There should be an option to stub globally by disabling WebMock.reset! conditionally. That way the preferred "each example in a clean state with its own setup" approach is the default, but can be overridden if necessary.

Epigene avatar Oct 13 '17 14:10 Epigene

@Epigene Do you have any suggestion how that option to disable reset conditionally could work?

btw. you don't have to include webmock/rspec config. You can define your own config.

bblimke avatar Oct 13 '17 19:10 bblimke

Now that I think about it, the functionality could work like this:

  1. Allow stubs to have optional metadata (maybe they already support something like that),
  2. Have a before(:all) call that sets up stubs marked as "global" WebMock.stub_request(metadata: {type: "global"}),
  3. Do not require 'webmock/rspec', instead roll your own reset with after(:each) { WebMock.reset!(except: {metadata: "global"}) } to explicitly keep the "global" mocks.
  4. Allow WebMock.reset! method to receive optional argument for reset exclusions,
  5. Allow WebMock.reset! method to receive optional argument for reset exclusions with a special :all argument to skip resetting completely.

5th point would be a quick-and-dirty way to skip reset entirely. If last call of WebMock.reset! dictates the behavior, then projects could have this kind of setup:

# in rails_helper.rb
after do
  WebMock.reset!
end

# in some spec file
describe "long setup" do
  after do
    WebMock.reset!(except: :all)
  end
end

Epigene avatar Oct 15 '17 15:10 Epigene

some news right here? Is this possible? Thanks

pacop avatar Dec 11 '18 07:12 pacop

yeah, we need this. for sure!

i don't wanna stub the same and same request over and over again?

krtschmr avatar Aug 06 '19 01:08 krtschmr

Has anybody found a workaround and be able to stub things once?

mejiaej avatar Jun 24 '21 22:06 mejiaej

@mejiaej https://www.rubydoc.info/github/bblimke/webmock/WebMock#globally_stub_request-class_method

kirylrb avatar Aug 22 '21 00:08 kirylrb

@mejiaej https://www.rubydoc.info/github/bblimke/webmock/WebMock#globally_stub_request-class_method

Thanks! Not the ideal scenario (I don't want to stub on every example) but this is what works so far.

RSpec.configure do |config|
  config.before :each do
    WebMock.globally_stub_request { |request|
      if request.uri.to_s =~ /my_url/
        { status: 200, body: '{}', headers: {} }
      end
    }
  end
end

jlurena avatar Oct 21 '21 17:10 jlurena