TLDR; você pode usar o método ActiveSupport :: Callbacks # run_callbacks para executar os callbacks manualmente.
Recentemente, movi alguma lógica para o before_save
retorno de chamada do ActiveRecord porque a lógica estava fortemente acoplada a como o modelo é armazenado no banco de dados e deve ser executado antes de cada salvamento no banco de dados para manter a integridade dos modelos.
class Activity < ActiveRecord::Base
has_one :trackable
has_one :topic
before_save :set_topic_from_trackable
# ...
end
No entanto, mover essa lógica para o retorno de chamada quebrou minha especificação de Activity.track
método.
describe Activity do
let(:topic) { Topic.new }
let(:trackable) { Comment.new(topic: topic))
before do
activity = Activity.new
allow( activity ).to receive(:save!)
allow( Activity ).to receive(:new) { activity }
end
describe '.track' do
subject{ Activity.track(comment) }
it "sets topic from trackable automatically"
expect( subject ).to have_received(:save!)
expect( subject.trackable ).to eql trackable
expect( subject.topic ).to eql trackable.topic
end
end
end
Como podemos consertar isso? Bem, há uma run_callbacks método em ActiveRecord
que eu encontrei durante a resolver esta questão e ele pode ser usado como este: some_model.run_callbacks(:save, :before)
. Acabei de adicionar isso ao activity.save
esboço e a especificação fica verde novamente!
allow( activity ).to receive(:save!) { activity.run_callbacks(:save) }