我使用的FactoryGirl 3.3.0 RoR 3.2.3为什么我的FactoryGirl回调不应该运行?
我有一个像这样has_one配置文件的用户模型;
class User < ActiveRecord::Base
has_secure_password
has_one :profile, dependent: :destroy
accepts_nested_attributes_for :profile, update_only: true
attr_accessible :email, :username, :password, :password_confirmation, :profile_attributes
before_create :build_profile
end
class Profile < ActiveRecord::Base
attr_accessible :first_name, :last_name
belongs_to :user
validates :user, presence: true
validates :first_name, presence: true, on: :update
validates :last_name, presence: true, on: :update
end
在我的RSpec的测试中,我需要有时防止before_create:build_profile运行,所以我可以有没有个人资料的用户。我用FactoryGirl回调管理这个
after(:build) {|user| user.class.skip_callback(:create, :before, :build_profile)}
我的用户工厂定义如下;
FactoryGirl.define do
factory :user do
sequence(:email) {|n| "user_#{n}@example.com"}
sequence(:username) {|n| "user_#{n}"}
password "secret"
factory :user_with_profile do
factory :new_user_with_profile do
before(:create) {|user| user.activated = false}
end
factory :activated_user_with_profile do
before(:create) {|user| user.activated = true}
end
end
factory :user_without_profile do
after(:build) {|user| user.class.skip_callback(:create, :before, :build_profile)}
factory :new_user_without_profile do
before(:create) {|user| user.activated = false}
end
factory :activated_user_without_profile do
before(:create) {|user| user.activated = true}
end
end
end
end
我的期望是,:new_user_without_profile
和:activated_user_without_profile
将从:user_without_profile
继承after(:build)
回调而:new_user_with_profile
和:activated_user_with_profile
工厂不会,但它不太那样工作。以下是控制台的一个摘录,以证明我的问题;
irb(main):001:0> user = FactoryGirl.create :new_user_with_profile
irb(main):002:0> user.profile
=> #<Profile id: 11, first_name: "", last_name: "", created_at: "2012-07-10 08:40:10", updated_at: "2012-07-10 08:40:10", user_id: 18>
irb(main):003:0> user = FactoryGirl.create :new_user_without_profile
irb(main):004:0> user.profile
=> nil
irb(main):005:0> user = FactoryGirl.create :new_user_with_profile
irb(main):006:0> user.profile
=> nil
于是,我第一次创建:new_user_with_profile,创建一个配置文件作为预期,但第二次(创建后:new_user_without_profile),它没有任何更多! after(:build)回调似乎没有再次被调用(如果我添加了一些代码来输出内容,我没有在终端中看到它)。我不知道这里有什么问题。还有其他人吗?
不,我没有尝试过,是的它确实有效。谢谢,至少让我的测试工作。但它确实是一个肮脏的解决方案 - 我宁愿了解这里实际发生了什么问题。 – brad 2012-07-10 18:09:18
这里发生的事情非常简单。看到'user.class.skip_callback(:create,:before,:build_profile)'你的声明?因为回调是在类而不是在类的实例上设置的,所以当你第一次调用'FactoryGirl.create:new_user_without_profile'时,它设置为跳过回调。稍后当你调用'FactoryGirl.create:new_user_with_profile'时,它自然没有回调集,因为你之前已经删除了。我的建议是把它放回去,就是这样。 – Gerry 2012-07-11 07:47:31
抱歉,但它不适合我。 – 2015-12-02 05:57:12