со ссылкой на пример @danivovich
class Part < ActiveRecord::Base
before_validation :strip_whitespace
protected
def strip_whitespace
self.title = self.title.strip
end
end
правильный способ написать спецификацию - это отдельно написать спецификацию для strip_whitespace метода, а затем просто проверить, установлен ли для класса модели обратный вызов, например:
describe Part do
let(:record){ described_class.new }
it{ described_class._validation_callbacks.select{|cb| cb.kind.eql?(:before)}.collect(&:filter).should include(:strip_whitespace) }
#private methods
describe :strip_whitespace do
subject{ record.send(:strip_whitespace)} # I'm using send() because calling private method
before{ record.stub(:title).and_return(' foo ')
it "should strip white spaces" do
subject.should eq 'foo'
# or even shorter
should eq 'foo'
end
end
end
если вам нужно пропустить поведение обратного вызова в некоторых сценариях, используйте
before{ Part.skip_callback(:validation, :before, :strip_whitespace)}
before{ Part.set_callback( :validation, :before, :strip_whitespace)}
Обновление от 20.01.2013
Кстати, я написал гем с помощью RSpec matchers, чтобы проверить это https://github.com/equivalent/shoulda-matchers-callbacks
В общем, я вообще не рекомендую обратный вызов. Они хороши, например, в этом вопросе, однако, как только вы сделаете более сложные вещи, такие как:
После создания ->
- ссылка на аккаунт пользователя
- создать уведомление
- отправить письмо администратору
... тогда вам нужно создать объект пользовательской службы, чтобы разобраться с этим и протестировать их отдельно.