18

I'm stuck on a test scenario.

I have a controller method:

def update
  @object = Object.find params[:id]
  # some other stuff
  @object.save
  rescue ActiveRecord::StaleObjectError
    # woo other stuff
end  

The first part I test with:

context '#update'
  let(:object) { double }

  it 'nothing fails' do
    # some other stuff
    expect(Object).to receive(:find).with('5').and_return(object)
    expect(object).to receive(:save).and_return(true)
    xhr :put, :update, id:5
    expect(response).to be_success
    expect(assigns(:object)).to eq(object)
  end
end

Now I want to test the ActiveRecord::StaleObjectError exception. I want to stub it, but I didn't find any solution how to do this.

So my question is, how to raise the ActiveRecord::StaleObjectError in an RSpec test?

Arturo Herrero
  • 12,772
  • 11
  • 42
  • 73
rob
  • 2,136
  • 8
  • 29
  • 37

2 Answers2

42

Like this, for example

expect(object).to receive(:save).and_raise(ActiveRecord::StaleObjectError)
Sergio Tulentsev
  • 226,338
  • 43
  • 373
  • 367
  • 1
    It's important to say, if error class need a arguments on your instantiate, can create a `let(:exc) { MyErrorClass.new(:some, :arg) } ` and pass into `.and_raise` method => `expect(object).to receive(:save).and_raise(exc)` – Rafael Gomes Francisco May 15 '23 at 22:32
9

I would do something like this:

describe '#update' do
  let(:object) { double }

  before do 
    allow(Object).to receive(:find).with('5').and_return(object)
    xhr(:put, :update, id: 5)
  end

  context 'when `save` is successful' do
    before do 
      allow(object).to receive(:save).and_return(true)
    end

    it 'returns the object' do
      expect(response).to be_success
      expect(assigns(:object)).to eq(object)
    end
  end

  context 'when `save` raises a `StaleObjectError`' do
    before do 
      allow(object).to receive(:save).and_raise(ActiveRecord::StaleObjectError) 
    end

    it 'is not successful' do
      expect(response).to_not be_success
    end
  end
end

Please note that I make a difference between stubbing methods in the test setup (I prefer allow in this case) and the actual expectation (expect).

spickermann
  • 100,941
  • 9
  • 101
  • 131