Patrick Brinich-Langlois
Patrick Brinich-Langlois

Reputation: 1429

Run an RSpec example with exception-raising code without raise_error

To test whether code raises an exception using RSpec, you can use a block with raise_error:

it "raises an exception" do
  expect { raise_an_exception }.to raise_error
end

Let's say you want to test whether the code that raises an exception does something else as well. Must you always use the above syntax?

# testing whether an error is raised
it "reraises exceptions" do
  expect { log_exception_and_reraise }.to raise_error(ExceptionClass)
end

# not testing whether an error is raised
it "logs errors" do
  expect(Rails.logger).to receive(:error)
  expect { log_exception_and_reraise }.to raise_error
end

# not testing whether an error is raised
it "sends errors to error tracker"
  expect(ErrorTracker).to receive(:send_error)
  expect { log_exception_and_reraise }.to raise_error
end

This works, but you're testing two separate things in each example (even though you don't want to). And you have to duplicate the raise_error expectation for each one.

I'd rather do something like

it "sends errors to error tracker"
  expect(ErrorTracker).to receive(:send_error)
  execute { log_exception_and_reraise }
end

Upvotes: 1

Views: 1253

Answers (1)

bosskovic
bosskovic

Reputation: 2054

I see nothing wrong with how you wrote it. If you do not want to test multiple assertions in the same test, then you can split them, but if the test triggers an exception, you have to expect it.

Was that what you asked?

Btw, it is a bad practice to just raise_error. Its much better to pass it the correct class of exception that you expect, for example:

expect { log_exception_and_reraise }.to raise_error(ActiveRecord::RecordNotFound)

Upvotes: 1

Related Questions