Don't assert exceptions in feature specs

Posted . Visible to the public. Repeats.

As we are slowly switching from Cucumber scenarios to RSpec feature specs, you might be tempted to write assertions like this one:

feature 'authorization for cards management' do
  let(:guest_user) { create(:user, :guest) }

  scenario "rejects guest users from adding new cards", js: true do
    sign_in guest_user

    expect { visit new_cards_path }.to raise_error(Consul::Powerless)
  end
end

While this might work under certain circumstances¹, there is a good chance you'll see two exceptions when running this single spec:

  • expected Consul::Powerless but nothing was raised
  • No power to ['creatable_cards']

The reason for this behavior is that the Capybara test server is running in another thread, and the RSpec thread can't "see" the exception at this point in time.
As we are emulating a user interacting with the Browser, you should not write such assertions in feature specs anyway. Instead, you could:

  • write the same test as a request spec
  • expect what the user sees in this situation, e.g. an error flash.

¹

  • Rack::Test features emulate the server within the same thread and will therefore "see" those exceptions
  • The test thread and server thread of a JS-spec actually both have access to the last occured exception, but only before the next interaction. So technically you could add a line like visit new_cards_path after sign_in in the example above to make it green.
Michael Leimstädtner
Last edit
Michael Leimstädtner
License
Source code in this card is licensed under the MIT License.
Posted by Michael Leimstädtner to makandra dev (2023-07-11 07:04)