我想对@luizbranco的回答进行改进,以便在创建其他用户时使after_save回调更具通用性。
FactoryGirl.define do
factory :user do
first_name "Luiz"
last_name "Branco"
after(:build) { |user|
user.class.skip_callback(:create,
:after,
:run_something1,
:run_something2)
}
trait :with_after_save_callback do
after(:build) { |user|
user.class.set_callback(:create,
:after,
:run_something1,
:run_something2)
}
end
end
end
没有使用 after_save 回调函数的运行:
FactoryGirl.create(:user)
在 after_save 回调函数中运行:
FactoryGirl.create(:user, :with_after_save_callback)
在我的测试中,我更喜欢默认情况下不使用回调函数创建用户,因为使用的方法会运行一些额外的东西,而这些东西通常不是我想要在测试例子中使用的。
----------更新------------
我停止使用skip_callback,因为测试套件存在一些不一致的问题。
替代方案1(使用stub和unstub):
after(:build) { |user|
user.class.any_instance.stub(:run_something1)
user.class.any_instance.stub(:run_something2)
}
trait :with_after_save_callback do
after(:build) { |user|
user.class.any_instance.unstub(:run_something1)
user.class.any_instance.unstub(:run_something2)
}
end
备选方案2(我首选的方法):
after(:build) { |user|
class << user
def run_something1; true; end
def run_something2; true; end
end
}
trait :with_after_save_callback do
after(:build) { |user|
class << user
def run_something1; super; end
def run_something2; super; end
end
}
end
:on => :create
的验证,可以使用after(:build) { |user| user.class.skip_callback(:validate, :create, :after, :run_something) }
。 - James ChevalierClass.skip_callback
调用将在其他测试中保持持久性,因此,如果您尝试反转跳过回调逻辑,则其他测试期望回调发生的话将失败。 - mpdaughertyafter(:build)
块中进行存根。这样可以让你的工厂默认运行回调函数,而不需要在每次使用后重置回调函数。 - mpdaughertyafter_save: my_method
,那么在工厂中的语法就是skip_callback(:save, :after, :my_method)
。 - Michael Mudge