工厂女孩after_initialize

时间:2016-08-25 15:26:59

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

我有两个ActiveRecord模型用户和帖子。这是我的用户模型。

class User < ActiveRecord::Base
  has_many :posts

end

这是我的Post模型。

class Post < ActiveRecord::Base
  belongs_to :user
  after_initialize :set_name


  private
  def set_name
    self.name = "Post #{self.user.posts.count + 1}"
  end

end

这一切都很好,但是当我写工厂时

FactoryGirl.define do
  factory :post do
    content 'blah blah'
    user
  end
  factory :user do
    name 'Dummy name'
  end
end

这是我的post_spec.rb文件

require 'rails_helper'

RSpec.describe Post do
  context 'with valid values' do
    it 'should be valid' do
      expect(build(:post)).to be_valid
    end
  end
end

我的测试用例说不清楚

  

set_name

中nil类的未定义方法帖子

我不知道我哪里出错了。

3 个答案:

答案 0 :(得分:0)

patkoperwas是正确的,您正在尝试在拥有关联的User对象之前初始化Post,您的after_initialize需求首先存在。如果必须使用after_initialize,则可以在创建Post之前创建一个创建User的工厂,然后使用该工具进行构建。

FactoryGirl.define do
  factory :user do
    name "blah blah"

    factory :user_with_posts do
       transient do
        post_count = 1
       end
       after(:create) do |user, evaluator|
         evaluator.post_count.times do
           create :post, user: user
         end
       end
    end
  end
end

我不相信FactoryGirl中内置了(:build)功能。因此,在构建Post对象之前,您无法真正使用回调来创建用户。我要么创建一个user_with_post,要么显式创建一个用户,并在创建一个post对象时传入它。

RSpec.describe Post do
  context 'with valid values' do
    it 'should be valid' do
      user = FactoryGirl.create :user_with_posts
      post = user.posts.first
      expect(post).to be_valid
    end
end

答案 1 :(得分:-1)

您需要配置该关联https://github.com/thoughtbot/factory_girl/blob/master/GETTING_STARTED.md#associations

FactoryGirl.define do
  factory :user do
    name 'Dummy name'
  end

  factory :post do
    content 'blah blah'
    association :user
  end
end

如果您在没有用户的情况下使用工厂创建帖子,FactoryGirl将为您创建用户,如果您之前创建了用户并在创建帖子时传递了该用户,FactoryGirl将使用您提供的用户。

答案 2 :(得分:-1)

您可以像这样在Post工厂中使用with_initialize

factory :post do
  content 'blah blah'
  user

  initialize_with { new(user: user) }
end

问题的原因在factory_bot文档中进行了描述:https://github.com/thoughtbot/factory_bot/blob/master/GETTING_STARTED.md#custom-construction

为获得与ActiveRecord的最大兼容性,默认的初始化程序通过不带任何参数的构建类上调用new来构建所有实例。然后调用属性编写器方法来分配所有属性值。

这就是为什么Post工厂的after_initialize钩中没有关联的用户。

相关问题