xxjjnn
xxjjnn

Reputation: 15239

Rails rspec Error.should_receive

When I want to test that a method raises an error its quite simple:

# There is a Widget model

# Method to test

class Example
  def perform(widget_id)
    the_widget = Widget.find(widget_id)
  end
end

# rspec test

describe "Example" do
  let(:example) {Example.new}

  it "does not find the record and raises an error" do
    expect { example.perform(0) }.to raise_error( ActiveRecord::RecordNotFound )
  end

But if that method handles errors:

class Example
  def perform(widget_id)
    the_widget = Widget.find(widget_id)
  rescue ActiveRecord::RecordNotFound => e
    # (error logging goes here)
    return false
  end
end

Then the expect __ to raise_error __ is not met, as the exception is handled. So what I'm asking, is if there is something which merely checks to see if an error was raised, irrespective of whether it was handled. Such as:

Error.should_receive(ActiveRecord::RecordNotFound)

There is always the option to work around the problem by checking to see if its logged, but this question isn't about solving this problem, its about the general solution of determining if an error has been raised

Upvotes: 1

Views: 99

Answers (1)

Peter Alfvin
Peter Alfvin

Reputation: 29389

RSpec allows you to set expectations for:

  • The value of an object
  • Whether an object receives messages at some point in the future and what arguments it receives them with
  • Whether a test double has received messages at some point in the past and what arguments it received them with
  • What behavior a block has on the outside world when it executes

With respect to some method you are testing, you can therefore test:

  • What value it returns
  • What methods it calls and what parameters it calls them with
  • What errors it raises
  • What changes in state occur as a result of it's execution

What you cannot do, however, is test what values are returned or errors raised by methods that it calls. That's consistent with the fact that RSpec enables you to test a method's externally detectable behavior, not it's internal behavior or the behavior of any code it may depend on.

Upvotes: 1

Related Questions