Записи FactoryGirl не сохраняются

#ruby-on-rails #ruby #factory-bot

#ruby-on-rails #ruby #завод-бот

Вопрос:

Я пытаюсь написать тесты, в которых сохраняются объекты компании. Но объекты компании не сохраняются, и в таблице нет записи о компании. Почему и как я могу решить проблему?

db/schema.rb

 ActiveRecord::Schema.define(version: 20140626075006) do
  create_table "companies", force: true do |t|
    t.string   "name"
    t.datetime "created_at"
    t.datetime "updated_at"
  end
end
 

приложение / модели/company.rb

 class Company < ActiveRecord::Base
end
 

спецификация/фабрики /companies.rb

 FactoryGirl.define do
  factory :company do
    name "MyString"
  end
end
 

спецификация /модели/компания_spec.rb

 require 'spec_helper'

describe Company do
  let(:company) { FactoryGirl.create(:company) }
  context "test context"do
    it "test" do
      Company.first.name
    end
  end
end
 

спецификация / spec_helper.rb

 ENV["RAILS_ENV"] ||= 'test'
require File.expand_path("../../config/environment", __FILE__)
require 'rspec/rails'
require 'rspec/autorun'
Dir[Rails.root.join("spec/support/**/*.rb")].each { |f| require f }
RSpec.configure do |config|
  config.fixture_path = "#{::Rails.root}/spec/fixtures"
  config.use_transactional_fixtures = true
  config.infer_base_class_for_anonymous_controllers = false
  config.order = "random"
end
 

Результат

 /Users/machidahiroaki/.rvm/rubies/ruby-2.0.0-p451/bin/ruby -e $stdout.sync=true;$stderr.sync=true;load($0=ARGV.shift) /Users/machidahiroaki/RubymineProjects/rspec_sample/bin/rake spec
Testing started at 19:48 ...
/Users/machidahiroaki/.rvm/rubies/ruby-2.0.0-p451/bin/ruby -S rspec ./spec/bowling_spec.rb ./spec/models/company_spec.rb

NoMethodError: undefined method `name' for nil:NilClass
./spec/models/company_spec.rb:7:in `block (3 levels) in <top (required)>'

2 examples, 1 failure, 1 passed

Finished in 0.090546 seconds
/Users/machidahiroaki/.rvm/rubies/ruby-2.0.0-p451/bin/ruby -S rspec ./spec/bowling_spec.rb ./spec/models/company_spec.rb failed

Process finished with exit code 1
 

Ответ №1:

Ах, пару раз это обжигало.

let выражения вычисляются лениво. Вы не ссылались на это, поэтому company оно так и не было создано. Вы можете использовать let! , например.

   let!(:company) { FactoryGirl.create(:company) }
 

Или ссылайтесь на это company

 let(:company) { FactoryGirl.create(:company) }
context "test context"do
  it "test" do
    expect(company).to_not be_nil
    expect(Company.count).to eq 1
  end
end
 

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

1. Это работает. Большое вам спасибо. Однако, когда я ставлю точку останова на «ожидать (Company.count). к уравнению 1» и запустите его, в таблице компаний нет записи. почему это происходит?

2. @HiroakiMachida: С тех пор, как вы use_transactional_fixtures , все спецификации выполняются в транзакции базы данных. Идея состоит в том, что транзакция не будет зафиксирована и, следовательно, откатится в конце примера. Такое поведение быстрее, чем удаление всех данных вручную из базы данных вручную после запуска набора тестов. Незафиксированные транзакции не видны другим подключениям к базе данных, поэтому точка останова не может видеть запись.