Victor Ivanov
Victor Ivanov

Reputation: 23

How to test side effect of the method which raises error

I have a method like:

def method
  # ..
  begin
    some_invokation
  rescue StandardError
    # some_other_stuff
    raise
  end
  # ..
  User.create!
end

Right now I can test that this method raises the exception:

expect { method }.to raise_error(StandardError)

But also I would like to test that the user is not created.

expect { method }.not_to change { User.count }

It doesn't work. It shows that the exception was raised. I tried to mock raise invocation:

allow_any_instance_of(described_class).to receive(:raise)

But in this case my method is not interrupted and the user is created. Are there any other ways to do it?

Upvotes: 2

Views: 899

Answers (3)

burennto
burennto

Reputation: 36

Instead of using

expect { robot.greet }.to raise_error

you can method stub the raise to prevent it from breaking the other examples:

class Robot
  def greet
    puts 'Hello World'
    raise 'malfunction'
  end
end
RSpec.describe Robot do
  let(:robot) { Robot.new }

  describe '#greet' do
    before do
      allow(robot).to receive(:puts)
      allow(robot).to receive(:raise)
      robot.greet
    end

    it 'prints a message to console' do
      expect(robot).to have_received(:puts).with('Hello World')
    end

    it 'malfunctions' do
      expect(robot).to have_received(:raise)
    end
  end
end

Upvotes: 0

spickermann
spickermann

Reputation: 106882

Perhaps something like:

expect { 
  method rescue nil
}.not_to change { User.count }

Upvotes: 4

CraigM
CraigM

Reputation: 194

This might do it:

expect { method }.to raise_error(StandardError)
expect { method rescue 'method rescued' }.to eq('method rescued')
expect { method rescue 'method rescued' }.not_to change { User.count }

Upvotes: 1

Related Questions