ruby-on-rails - Rspec,使用 has_many 构建的 Factory Girl

标签 ruby-on-rails ruby-on-rails-4 rspec factory-bot rspec-rails

我有一个具有一对多关系的模型,它们是 Poll 和 Choice。

我该如何正确测试它们,因为下面的代码导致 ActiveRecord::RecordInvalid:。我想随时随地创建父级 (Poll) 及其子级 (Choices),而不是先创建父级 (Poll) 然后再创建父级 (Poll)之后保存 child (Choices)。

代码如下:

首先,我得到的所有测试用例的错误:

Failure/Error: @poll = FactoryGirl.build(:poll_with_choices, user: @user)
 ActiveRecord::RecordInvalid:
   Validation failed: Choices choices required at least 2

投票模型:

class Poll < ActiveRecord::Base
  belongs_to :user
  has_many :choices
  accepts_nested_attributes_for :choices

  validates :title, presence: true
  validates_each :choices do |record, attr, value| 
    record.errors.add attr, "choices required at least 2" if record.choices.length < 2
  end
end

投票工厂:

FactoryGirl.define do
  factory :poll do
    title { FFaker::Lorem.phrase }
    description { FFaker::Lorem.sentences }
    user

    factory :poll_with_choices do  
      transient do 
        choices_count 3
      end

      after(:build) do |poll, evaluator|
        build_list(:choice, evaluator.choices_count)
      end
    end
  end
end

选择工厂:

FactoryGirl.define do
  factory :choice do
    label { FFaker::Name.name }
    votes 0
    poll
  end
end

投票规范

require 'rails_helper'

RSpec.describe Poll, type: :model do
  before do 
    @user = FactoryGirl.create(:user)
    @poll = FactoryGirl.build(:poll_with_choices, user: @user) 
  end

  subject { @poll }

  it { should respond_to(:title) }
  it { should respond_to(:description) }

  it { should validate_presence_of(:title) }

  it { should belong_to(:user) }
  it { should have_many(:choices) }
  it { should accept_nested_attributes_for(:choices) }

  describe "#save" do 
    before do 
      @user = FactoryGirl.create(:user)
    end

    it "success" do 
      poll = FactoryGirl.build(:poll_with_choices, user: @user)
      expect(poll.save).to eql true
    end

    it "fail" do 
      poll = FactoryGirl.build(:poll, user: @user)
      poll.choices = FactoryGirl.build_list(:choice, 1)
      expect(poll.save).to eql false
    end
  end
end

作为 FactoryGirl.create 的引用,不是 FactoryGirl.build:http://www.rubydoc.info/gems/factory_girl/file/GETTING_STARTED.md#Associations

提前致谢。

最佳答案

最后我使用 FactoryGirl trait 和 attributes

这是 poll 工厂代码:

FactoryGirl.define do
  factory :poll do
    title { FFaker::Lorem.phrase }
    description { FFaker::Lorem.sentences }
    user
    choices_attributes { [FactoryGirl.attributes_for(:choice),     FactoryGirl.attributes_for(:choice), FactoryGirl.attributes_for(:choice)] }

    trait :with_many_choices do 
      choices_attributes { [
        FactoryGirl.attributes_for(:choice), FactoryGirl.attributes_for(:choice), 
        FactoryGirl.attributes_for(:choice), FactoryGirl.attributes_for(:choice), 
        FactoryGirl.attributes_for(:choice), FactoryGirl.attributes_for(:choice)
      ] }
    end

    trait :with_invalid_choices do 
      choices_attributes { [FactoryGirl.attributes_for(:choice),     FactoryGirl.attributes_for(:choice), FactoryGirl.attributes_for(:choice, label: '')] }
    end

    trait :with_lack_of_choices do 
      choices_attributes { [FactoryGirl.attributes_for(:choice)] }
    end

    trait :without_choices do 
      choices_attributes { [] }
    end
  end
end

引用资料(感谢):

关于ruby-on-rails - Rspec,使用 has_many 构建的 Factory Girl,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32450502/

相关文章:

ruby-on-rails - 无法安装 json gem 1.8.6 - 无法在 Ubuntu 上构建 gem native 扩展

ruby-on-rails - Ruby on Rails 4 和 Simple Form 中 "helpers"的可用 i18n 翻译列表?

ruby-on-rails - accept_nested_attributes_for :allow_destroy, :_destroy 不工作

ruby-on-rails - Factory_Girl Rspec 的 "Uninitialized constant User"

ruby-on-rails - 新部署后 Unicorn 未正确断开数据库连接

javascript - 如何根据在rails简单表单中选中的单选按钮渲染输入表单

ruby-on-rails - 事件管理员更改 csv 的 header 并向输出添加文本

javascript - Rails 上带有 selenium 的 chromedriver

ruby-on-rails - Rspec:测试 CSV 输出中的行数

ruby-on-rails - 如何使用 rspec 测试选择日期?