Falko
Falko

Reputation: 1035

Rspec raise error not working as expected, need correct syntax

I'm testing a class raises an error

context 'with no office manager' do
      let(:expected_response) do
        {
            error: "No office manager"
        }
      end
      it 'returns an error' do
        expect{ subject.run }.to raise_exception(an_instance_of(StandardError).and having_attributes(expected_response))
      end
    end

Gets the failed test response:

expected Exception with an instance of StandardError and having attributes {:error => "No office manager"}, got #<StandardError: {:error=>"No office manager"}>

What's the correct syntax to make this pass?

Upvotes: 4

Views: 2189

Answers (2)

Viktor
Viktor

Reputation: 2773

An exception in Ruby has a #message method/attribute, but not #error. So you need to change

let(:expected_response) do
  {
    error: "No office manager"
  }
end

to

let(:expected_response) do
  {
    message: "No office manager"
  }
end

Upvotes: 1

Sebasti&#225;n Palma
Sebasti&#225;n Palma

Reputation: 33420

I can say that's not so common to pass an object to an exception more than a string to hint the one that's reading it (or maybe also the caller). But if you want to check that, you can try passing a block to raise_error and expect the block argument message method is equal to the second argument for raise:

RSpec.describe 'raise plus a non-string second argument' do
  context 'with no office manager' do
    let(:expected_response) do
      { error: 'No office manager' }
    end

    it 'returns an error' do
      expect do
        raise StandardError, expected_response
      end.to raise_error(StandardError) { |error| expect(error.message).to eq expected_response.to_s }
    end
  end
end

Notice, raise_error and raise_exception are functionally interchangeable, so, you can use the one that makes the most sense to you in any given context.

Upvotes: 1

Related Questions