1

I'm testing a Rails application using RSpec/Capybara and Webmock. I'm setting js:true for a particular suite of tests, whilst stubbing out a web request using Webmock in a before block.

One of the tests fails intermittently - the error returned is that I haven't stubbed the web request (but I have!).

<WebMock::NetConnectNotAllowedError: Real HTTP connections are disabled... >

My tests are set up as follows:

RSpec.feature 'Viewing something', type: :feature, js: true do
  before do
    body = { 'report': [{ 'data': [1,2,3] }] }.to_json
    stub_request(:post, 'https://www.some-url.com').to_return(status: 200, body: body, headers: {'Content-Type' => 'aplication/json'})
    sign_in_user
  end
  # Failing test:
  it 'does something' do
    expect(page).to have_text 'Something'
  end
  # Passing test:
  context 'With a different stubbed result' do
    before do
      body = {'report': []}.to_json
      stub_request(:post, 'https://www.some-url.com').to_return(status: 200, body: body, headers: {'Content-Type' => 'aplication/json'})
    end
    it 'shows something else do
      expect(page).to have_text 'Something else'
    end
  end
end

If I change my main before block so that it signs in the user before setting the stub, the test passes, i.e this works:

before do
    sign_in_user
    body = { 'report': [{ 'data': [1,2,3] }] }.to_json
    stub_request(:post, 'https://www.some-url.com').to_return(status: 200, body: body, headers: {'Content-Type' => 'aplication/json'})
end

I assume this is because the javascript server only starts running when start 'using it' i.e. when I sign the user in. So if I set my stubs before that point, they don't exist?

Anyway, I feel there must be a nicer way to fix this - a way I can still define my stubs before running some test code in a javascript test?

Any ideas would be appreciated!

Lorelorelore
  • 3,335
  • 8
  • 29
  • 40
  • Is `sing_in_user` making a request? If so, stubbing the response before may cause it to not sign the user at all, making the spec failing (because you are not really signed in) – Greg Jan 07 '19 at 11:53
  • Where is the call to `some-url.com` being made from (your app code, or the front end code JS)? – Thomas Walpole Jan 07 '19 at 12:00
  • @meta `sign_in_user` just completes the sign in form and logs the user in. The error is from Webmock telling me that I haven't stubbed out the request in the before action. – abigail mcphillips Jan 07 '19 at 12:02
  • @ThomasWalpole the external request is being made from my app code. – abigail mcphillips Jan 07 '19 at 12:06
  • If the root cause is truly that Capybara has yet to start the app (although it’s unclear why that would make any difference) you could just use a `before(:all`)` block to to visit once initially to trigger the app startup – Thomas Walpole Jan 07 '19 at 12:43
  • Or a first matching example defined hook - https://relishapp.com/rspec/rspec-core/v/3-8/docs/hooks/when-first-matching-example-defined-hook – Thomas Walpole Jan 07 '19 at 12:50
  • @abigailmcphillips What I'm trying to say is that you maybe stub the request, log it user (which uses up the stubbed request), that could explain why it works when you change the order of things. IDK the internals, but that would be my suggestion to investigate. – Greg Jan 07 '19 at 14:05

0 Answers0