Baub
Baub

Reputation: 5044

Rspec Stub Fetched Model

How does one stub a model that gets fetched in the controller?

Example:

# Model Spec
it 'does something' do
  allow(model).to receive(:value).and_return 100
  model2 = FactoryGirl.create :model
  allow(model2).to receive(:value).and_return 99
  # next line fails because it returns 100. when fetched, model2.value = 0
  expect(model.subtract_last_model).to eq 1
end

# Model
def subtract_last_model
 value - Model.last.value
end

I need to be able to stub model2 aka Model.last to return 99.

I could, of course, write the following and then write a spec to see if this was called with the correct params, but I was curious if there was another way:

def subtract_model(model)
  value - model.value
end

Upvotes: 1

Views: 128

Answers (2)

Alexander Kireyev
Alexander Kireyev

Reputation: 10825

It' easy, just stub Model with model2:

it 'does something' do
  allow(model).to receive(:value).and_return 100
  model2 = FactoryGirl.create :model

  #  stub Model
  allow(Model).to receive(:last).and_return model2
  allow(model2).to receive(:value).and_return 99

  # next line fails because it returns 100. when fetched, model2.value = 0
  expect(model.subtract_last_model).to eq 1
end

Upvotes: 1

spickermann
spickermann

Reputation: 106792

Model.last does not return the stubbed model2, but reloads an unstubbed version of model2 from the database. Therefore:

it 'does something' do
  allow(model).to receive(:value).and_return 100
  model2 = FactoryGirl.create :model
  allow(model2).to receive(:value).and_return 99

  allow(Model).to receive(:last).and_return(model2)

  expect(model.subtract_last_model).to eq 1
end

Upvotes: 1

Related Questions