与工厂女孩测试和基本has_many关系

时间:2014-02-04 09:55:20

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

我正在关注此post on thoughbot,我在此处找到了解决问题的方法。

以下是两种模式:

class Admin::Post < ActiveRecord::Base
  has_many :sml, :class_name => "Admin::PostSml", :dependent => :destroy
    accepts_nested_attributes_for :sml, allow_destroy: true, reject_if: proc { |sml| sml[:fklang].blank? }
end

class Admin::PostSml < ActiveRecord::Base
  belongs_to :post
end

这是我用来测试它的工厂(根据博客文章中描述的内容):

FactoryGirl.define do
  factory :admin_post, :class => 'Admin::Post' do
    f_del 0
    published 1

    factory :post_sml do
      after_create do |post|
        create(:admin_post_sml, admin_post: post)
      end
    end
  end

  factory :admin_post_sml, :class => 'Admin::PostSml' do
    post_id 1
    fklang "it"
    title Faker::Lorem.word
    abastract Faker::Lorem.sentences
    description Faker::Lorem.paragraphs
    pub_date "2014-02-04 09:43:43"
    exp_date "2014-02-04 09:43:43"
  end

end

和相应的模型测试:

require 'spec_helper'

describe Admin::Post do
  it "should create post and sml for post" do
    post = FactoryGirl.create(:post_sml)

    post.should be_valid
  end
end

但如果我这样测试会给我错误:

Admin::Post should create post and sml for post
 Failure/Error: post = FactoryGirl.create(:post_sml)
 NoMethodError:
   undefined method `admin_post=' for #<Admin::PostSml:0x007ffbfe7345e0>
 # ./spec/factories/admin_posts.rb:10:in `block (4 levels) in <top (required)>'
 # ./spec/models/admin/post_spec.rb:5:in `block (2 levels) in <top (required)>'

我做错了什么?

如果我仅在测试日志中使用FactoryGirl.create(:admin_post)进行测试,则会看到正确的查询,用于创建admin_post行但不会创建相关的admin_post_sml行。

谢谢!

修改

最后我弄清楚如何让它发挥作用:

FactoryGirl.define do
  factory :admin_post, :class => 'Admin::Post' do
    f_del 0
    published 1

    factory :post_with_sml do
      after(:create) do |admin_post|
        create(:admin_post_sml, post: admin_post)
      end
    end
  end

  factory :admin_post_sml, :class => 'Admin::PostSml' do
    fklang "it"
    title Faker::Lorem.sentence
    abstract Faker::Lorem.sentence
    description Faker::Lorem.paragraph
    pub_date "2014-02-04 09:43:43"
    exp_date "2014-02-04 09:43:43"
  end

end

1 个答案:

答案 0 :(得分:0)

您应该使用特征,而不是嵌套工厂。您可以指定Post的特征,用它创建PostSml。

FactoryGirl.define do
  factory :admin_post, :class => 'Admin::Post' do
    f_del 0
    published 1

    trait :with_sml do
      after(:create) do |admin_post|
        create(:admin_post_sml, post: admin_post)
      end
    end
  end

  factory :admin_post_sml, :class => 'Admin::PostSml' do
    fklang "it"
    title Faker::Lorem.sentence
    abstract Faker::Lorem.sentence
    description Faker::Lorem.paragraph
    pub_date "2014-02-04 09:43:43"
    exp_date "2014-02-04 09:43:43"
  end
end

然后您可以像这样使用它:create(:admin_post, :with_sml)