rails / rspec:Fabricator - 测试关联(ActiveModel :: MissingAttributeError)

时间:2018-05-30 13:57:05

标签: ruby-on-rails ruby activerecord rspec fabricator

我正在为我的模型编写测试,并遇到了我似乎无法解决的错误。我使用的是rspec和Fabricator。在隔离测试时工作正常,但当我尝试测试关联时,我得到一个ActiveModel :: MissingAttributeError。

模型/ user.rb

nil

模型/ company.rb

class User < ApplicationRecord
  ...
  validates :email, uniqueness: true, presence: true
  belongs_to :company, required: false
end

模式

class Company < ApplicationRecord
  validates :organisation_number, uniqueness: true, presence: true
  has_many :users, dependent: :destroy
end

制造者/ user_fabricator.rb

create_table "companies", force: :cascade do |t|
  t.string "organisation_number"
  ...
end

create_table "users", id: :serial, force: :cascade do |t|
    t.string "email", default: "", null: false
    ...
    t.bigint "company_id"
    t.index ["company_id"], name: "index_users_on_company_id"
    ...
  end

制造者/ company_fabricator.rb

Fabricator :user do
  email { Faker::Internet.email }
  password '123456'
  confirmed_at Time.now
end

spec / user_spec.rb (第一次测试通过,第二次测试失败)

Fabricator :company do
  organisation_number { Faker::Company.swedish_organisation_number }
end

我也尝试过将公司直接添加到User制作者,就像这样(在我看来,这就像documentation的正确实现):

describe User do
  context '#create' do
    it 'Creates a user when correct email and password provided' do
      user = Fabricate(:user)
      expect(user).to be_valid
    end
    it 'Lets assign a company to user' do
      company = Fabricate(:company)
      expect(Fabricate.build :user, company: company).to be_valid
    end
  end
end

反之,将用户添加到公司制造商,如下所示:

Fabricator :user do
  email { Faker::Internet.email }
  password '123456'
  confirmed_at Time.now
  company
end

但两种方法都给我留下了同样的错误:

User#create让我们将公司分配给用户 失败/错误:公司=制造(:公司)
ActiveModel :: MissingAttributeError:无法写出未知属性&#39; company_id&#39;

关于我做错了什么的任何建议?

1 个答案:

答案 0 :(得分:1)

我会写出自己的答案,但我不确定我是否可以比RSpec更好地描述它,所以这可以直接来自Here

  

Rails 4.x ActiveRecord::Migration待迁移迁移检查

     

如果您不使用ActiveRecord,则无需担心这些问题   设置。

     

Rails 4.x的用户现在可以利用改进的架构迁移和同步功能。在RSpec 3之前,用户需要在开发和测试环境中手动运行迁移。此外,行为也有所不同,具体取决于规范是通过rake还是通过独立的rspec命令运行。

     

随着Rails 4的发布,新的API已经暴露出来   ActiveRecord::Migration。这允许RSpec利用这些新功能   标准迁移检查,全面镜像行为。

     
      
  • Rails 4.0.x

         

    在Rails之后将以下内容添加到rails_helper文件的顶部   被要求:

     ActiveRecord::Migration.check_pending!
    
         

    如果存在任何挂起的架构更改,则会引发异常。仍然需要用户手动保持开发和测试环境同步。

  •   
  • Rails 4.1 +

         

    这个版本有一个令人兴奋的新功能。用户不再需要保持开发和测试环境的同步。要利用此功能,在需要Rails之后将以下内容添加到rails_helper文件的顶部:

     ActiveRecord::Migration.maintain_test_schema!
    
         

    这样做的目的不仅仅是提高测试架构的时间   待迁移,Rails将尝试加载架构。一个例外   现在只有在架构之后存在挂起的迁移时才会引发   已加载。

         

    使用此功能时需要注意几点:

         
        
    • 迁移仍需要手动运行;虽然现在只需要在'开发'环境中完成

    •   
    • 将引发异常如果尚未初始化架构。该例外将提供说明rake db:migrate需要运行的说明。

    •   
  •   
     

可以选择不检查待处理的迁移。既然如此   实际上是Rails的一个特性,这个改变需要作为Rails的一部分来完成   组态。为此,请将以下内容添加到config/environments/test.rb文件中:

config.active_record.maintain_test_schema = false
     

新的RSpec项目无需担心这些命令,因为rails generate rspec:install会自动添加它们。