【问题标题】:Is there a clean way to test ActiveRecord callbacks in Rspec?有没有一种干净的方法来测试 Rspec 中的 ActiveRecord 回调?
【发布时间】:2012-10-14 14:28:46
【问题描述】:

假设我有以下 ActiveRecord 类:

class ToastMitten < ActiveRecord::Base
  before_save :brush_off_crumbs
end

是否有一种干净的方法来测试 :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

【问题讨论】:

    标签: ruby activerecord rspec callback


    【解决方案1】:

    使用run_callbacks

    这不那么老套,但并不完美:

    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
    

    使用这种技术来测试after_save 会更尴尬。

    【讨论】:

    • 这是我见过的最优雅的方式!非常感谢!
    • 控制器回调有类似run_callbacks 的东西吗?
    • 对于after_save,您可能只需将should_receive 放入块中并返回true,即:revenue_object.run_callbacks(:save) do; revenue_object.should_receive(:record_financial_changes); true; end
    猜你喜欢
    • 2022-08-11
    • 2014-10-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-12
    • 1970-01-01
    • 1970-01-01
    • 2020-07-02
    相关资源
    最近更新 更多