如何测试模块是否在控制器类包含时向before_filter添加方法

时间:2010-11-10 10:52:01

标签: ruby-on-rails ruby mocking rspec

我想知道你将如何解决这个问题

您想重构以下代码

class AController < ActionController::Base
  before_filter :the_method

protected
  def the_method
  end 
end

class AController < ActionController::Base
  include TheModule
end

但由于您是BDD爱好者,您必须先编写规范

describe TheModule do
  context "when included" do
    it "adds #the_method as a before_filter" do

      # insert your code here

    end
  end
end

换句话说,问题是:  如何编写一个规范来检查当包含在类(可能是控制器类)中时是否将TheModel#the_method添加为before_filter。

2 个答案:

答案 0 :(得分:1)

您可以检查回调调用的方法是否存在。

@model.methods.include?('before_callback_method_name')

然而,这只是检查回调运行的方法是否存在,而不是它的特定类型。

我找不到获取模型回调列表的方法。

唯一的选择是测试模型是否应该如果回调存在,即如果回调在更新时反转字符串,则在更新时检查字符串是否反转。

*编辑*

您可以检索回调列表,如下所示:

@u._validate_callbacks

它返回一个回调链,其中包含名称,重要的是,键入。

>> u._validate_callbacks.first.class
=> ActiveSupport::Callbacks::Callback
>> u._validate_callbacks.first.kind
=> :before
>> u._validate_callbacks.first.filter
=> :validate_associated_records_for_sites

现在应该能够准确测试它是否已加载。

答案 1 :(得分:1)

我是这样做的:

describe TheModule do
  context "when included" do
    it "adds #the_method as a before_filter" do
      instance = Object.new
      instance.class_eval do |klass|
        expects(:before_filter).with(:expensive_method)
        include TheModule
      end
    end
  end
end

因为我们不需要测试过滤前的行为。我们可以测试它是否正确执行。