Я бы хотел улучшить ответ @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(использование заглушки и отката):
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