rubocop-rspec icon indicating copy to clipboard operation
rubocop-rspec copied to clipboard

Cop idea: use with_message matcher instead of matching error message manually

Open Darhazer opened this issue 2 years ago • 2 comments

I often see checks on message expectations like

expect(subject.foo).to raise_error(Error) do |error|
  expect(error.message).to match(/..../)
end

while raise_error offers .with_message

Darhazer avatar Mar 25 '22 10:03 Darhazer

I'm not certain why .with_message is specifically needed, as raise_error itself accepts a second argument for message matching:

 expect { raise "oops" }.to raise_error(RuntimeError, /op/)

It might be failure messages are slightly different, needs to be checked.

pirj avatar Mar 25 '22 12:03 pirj

@pirj Both .with_message and raise_error's second argument give exactly same errors, I'm not sure which one to prefer for this cop:

Failures:

  1) Errors runs raise_error with block
     Failure/Error:
       expect { 1 }.to raise_error(StandardError) do |error|
         expect(error.message).to eq('foo')
       end
     
       expected StandardError but nothing was raised
     # ./raise_spec.rb:7:in `block (2 levels) in <top (required)>'

  2) Errors runs raise_error.with_message string
     Failure/Error: expect { 1 }.to raise_error(StandardError).with_message('foo')
       expected StandardError with "foo" but nothing was raised
     # ./raise_spec.rb:13:in `block (2 levels) in <top (required)>'

  3) Errors runs raise_error.with_message string
     Failure/Error: expect { 1 }.to raise_error(StandardError).with_message(/foo/)
       expected StandardError with message matching /foo/ but nothing was raised
     # ./raise_spec.rb:17:in `block (2 levels) in <top (required)>'

  4) Errors runs raise_error & second argument string
     Failure/Error: expect { 1 }.to raise_error(StandardError, 'foo')
       expected StandardError with "foo" but nothing was raised
     # ./raise_spec.rb:21:in `block (2 levels) in <top (required)>'

  5) Errors runs raise_error & second argument regex
     Failure/Error: expect { 1 }.to raise_error(StandardError, /foo/)
       expected StandardError with message matching /foo/ but nothing was raised
     # ./raise_spec.rb:25:in `block (2 levels) in <top (required)>'

tejasbubane avatar Jan 04 '23 22:01 tejasbubane