有没有一种干净的方法来测试Rspec中的ActiveRecord回调?

Nat*_*ong 6 ruby activerecord rspec callback

假设我有以下ActiveRecord类:

class ToastMitten < ActiveRecord::Base
  before_save :brush_off_crumbs
end
Run Code Online (Sandbox Code Playgroud)

有没有一种干净的测试方法:brush_off_crumbs已被设置为before_save回调?

通过"干净"我的意思是:

  1. "没有实际储蓄",因为
    • 这很慢
    • 我并不需要测试的ActiveRecord正确处理一个before_save指令; 我需要测试一下,我正确告诉它在保存之前该做什么.
  2. "没有黑客攻击无证方法"

我发现了一种满足标准#1而不是#2的方法:

it "should call have brush_off_crumbs as a before_save callback" do
  # undocumented voodoo
  before_save_callbacks = ToastMitten._save_callbacks.select do |callback|
    callback.kind.eql?(:before)
  end

  # vile incantations
  before_save_callbacks.map(&:raw_filter).should include(:brush_off_crumbs)
end
Run Code Online (Sandbox Code Playgroud)

Nat*_*ong 9

使用 run_callbacks

这不那么hacky,但不完美:

it "is called as a before_save callback" do
  revenue_object.should_receive(:record_financial_changes)
  revenue_object.run_callbacks(:save) do
    # Bail from the saving process, so we'll know that if the method was 
    # called, it was done before saving
    false 
  end
end
Run Code Online (Sandbox Code Playgroud)

使用这种技术测试一个after_save会更加尴尬.

  • 对于`after_save`,你可能只是将`should_receive`放在块中并返回true,即:`revenue_object.run_callbacks(:save)do; revenue_object.should_receive(:record_financial_changes); 真正; end` (2认同)