Lucy Bain
Lucy Bain

Reputation: 2626

Rspec: Custom failure message for raise_error test

I'd like to use customised failure messages when testing if an error was raised or not while visiting a page with capybara.

My code:

expect(visit '/page/path').to_not raise_error(ActionView::Template::Error), "my custom error message"

I have also tried to use the lambda syntax (lambda { "my custom error message" }) with no success.

The problem seems to be that the error itself gets precedence for display over my custom error message. I have no interest in the error message - if one is raised, I know what the problem is, and the custom error message gives the solution (it's a long story involving VCR).

Right now I have a sketchy begin/rescue that looks like this:

begin
  expect(visit '/page/path').to_not raise_error(ActionView::Template::Error)
rescue ActionView::Template::Error => error
  expect(1).to eq(0), "my custom error message"
end

But, as you can see, I have to write a fake, always failing test, expect(1).to eq(0) which seems silly.

Is there any way to force my message to be displayed from the inline custom error message?

Upvotes: 2

Views: 2246

Answers (2)

Leonard Garvey
Leonard Garvey

Reputation: 1547

First of all you'll need to pass the block you want to execute to the expect method in order for the raise_error matcher to catch the errors raised in the block. Perhaps surprisingly the following fails for this reason:

describe 'Foo' do
  it 'raises an error' do
    expect(fail "wat").to raise_error(RuntimeError)
  end
end

But if we re-write that expectation as follows it passes:

expect{fail "wat"}.to raise_error(RuntimeError)

As Rob mentioned though if you want to specify that an error is not raised you'll need to write your expectation as follows:

expect{fail "wat"}.to_not raise_error

and using that format you can specify a custom error message:

expect{fail "wat"}.to_not raise_error, "custom error message"

The reason why your second block of code seems to work is your visit '/page/path' raises an exception, then your exception handler catches it. It would be equivalent to the following:

begin
  visit '/page/path'
rescue ActionView::Template::Error => error
  expect(1).to eq(0), "my custom error message"
end

Upvotes: 3

Rob Howard
Rob Howard

Reputation: 1819

I have the following working locally:

expect { visit '/page/path' }.to_not raise_error, "Nope"

Specifying the class of exception you expect to_not have raised is apparently deprecated, according to RSpec's yelling at the top of the test results:

DEPRECATION: `expect { }.not_to raise_error(SpecificErrorClass)` is
deprecated. Use `expect { }.not_to raise_error` (with no args) instead.

Upvotes: 2

Related Questions