Rspec — учетная запись для записи с определенным идентификатором

#ruby-on-rails #ruby #rspec

#ruby-on-rails #ruby #rspec

Вопрос:

У меня есть модель Trip, которая устанавливает значение по умолчанию для ‘refund_policy’ на ‘refund_policy’ компании этой поездки. Компания сама по себе имеет значение по умолчанию для ‘refund_policy’ в соответствии с политикой компании с идентификатором 4.

Мои тесты на наличие допустимой фабрики для Trip завершаются неудачей, как и многие другие, потому что в базе данных нет компании с идентификатором 4. Я попытался указать компанию с явным идентификатором. Кроме того, мои попытки заблокировать эту компанию или ее политику возврата пока не сработали.

Все используемые фабрики действительны, как определено предыдущими тестами.

Я пытался:

 #trip_spec.rb
describe Trip do
  let(:company) { FactoryGirl.build(:company) }
  let(:refund_policy) { 'example refund policy' }

  before do
    company.stub(:refund_policy).and_return(refund_policy)
    Company.stub(:find).and_return(company)
  end

  it "has a valid factory" do
    expect( FactoryGirl.build :trip, company_id: company.id ).to be_valid
  end
end
  

Я также пытался:

 let(:company)       { FactoryGirl.build(:company, id: 4) }

it "has a valid factory" do
  expect( FactoryGirl.build :trip ).to be_valid
end
  

А также:

 let!(:company)       { FactoryGirl.create(:company, id: 4) }

it "has a valid factory" do
    expect( FactoryGirl.build :trip ).to be_valid
end
  

Все это приводит к этому сообщению об ошибке

 # gives this error
Trip has a valid factory
  Failure/Error: let(:company) { FactoryGirl.build(:company) }
  ActiveRecord::RecordNotFound:
    Couldn't find Company with id=4

 # ./app/models/company.rb:70:in `default_refund_policy'
 # ./app/models/company.rb:66:in `set_defaults'
 # ./spec/models/trip_spec.rb:5:in `block (2 levels) in <top (required)>'
  

Значение по умолчанию для политики возврата за поездку

 #trip.rb
def set_defaults
  self.refund_policy = company.refund_policy if company amp;amp; (refund_policy.blank? || (refund_policy amp;amp; refund_policy.strip.length == 0))
end
  

Значение по умолчанию для политики возврата компании

 #company.rb
def set_defaults
  self.refund_policy = default_refund_policy if refund_policy.blank? || (refund_policy amp;amp; refund_policy.strip.length == 0)
end

def default_refund_policy
  Company.find(4).refund_policy
end
  

Как я могу эффективно учитывать этот путь значений по умолчанию?

Заранее спасибо.

Комментарии:

1. Можете ли вы попробовать let!(:company) { FactoryGirl.create(:company, id: 4) }

2. Только что попробовал. Изменений нет.

Ответ №1:

Все три завершаются ошибкой, потому что set_defaults вызывается как часть процесса сборки, который по очереди вызывает, default_return_policy который по очереди вызывает find . При существующем рабочем коде вам потребуется заглушка Company.find перед попыткой создания компании.

Кроме того:

  • Ваш второй пример не сработал бы, потому что вы используете build вместо create
  • Ваш третий пример не сработал бы, потому что вы используете let вместо let! и не ссылаетесь на переменную в вашем примере.

Следующее должно, по крайней мере, приблизить вас:

 describe Trip do
  before do
    company = InstanceDouble(Company, refund_policy: 'example refund policy')
    Company.stub(:find).and_return(company)
  end

  it "has a valid factory" do
    expect( FactoryGirl.build :trip, company_id: company.id ).to be_valid
  end
end
  

Комментарии:

1. Я думаю, проблема в том, что мне нужна компания с идентификатором 4, прежде чем я смогу даже создать новую компанию.

2. Да, это было началом правильного пути, спасибо. Я переключил ‘InstanceDouble’ на просто ‘double’, присвоил ему идентификатор 4 и политику возврата, и вуаля!

3. Я также обновил ваш метод заглушки до текущего синтаксиса: разрешить (Company).получать(:find).and_return(company)