Rspec如何为重写方法设置超类的期望值

时间:2011-11-16 17:55:55

标签: ruby-on-rails activerecord rspec

我有一个覆盖update_attributes的模型类:

class Foo < ActiveRecord::Base
  def update_attributes(attributes)
    if super(attributes)
      #do some other cool stuff
    end
  end
end

我正在试图弄清楚如何在update_attributes的超级版本上设置期望和/或存根,以确保在成功的情况下完成其他工作。另外,我想确保实际上正在调用super方法。

这是我到目前为止所尝试的内容(当然它没有用):

describe "#update_attributes override" do
  it "calls the base class version" do
    parameters = Factory.attributes_for(:foo)
    foo = Factory(:foo, :title => "old title")
    ActiveRecord::Base.should_receive(:update_attributes).once
    foo.update_attributes(parameters)
  end
end

当然,这不起作用:

Failure/Error: ActiveRecord::Base.should_recieve(:update_attributes).once
 NoMethodError:
   undefined method `should_recieve' for ActiveRecord::Base:Class

有什么想法吗?

2 个答案:

答案 0 :(得分:3)

update_attributes是一个实例方法,而不是一个类方法,所以你不能直接在ActiveRecord::Base上使用rspec-mocks将它存根,据我所知。而且我认为你不应该这样做:使用super是一个实现细节,你不应该将你的测试结合起来。相反,最好编写指定您想要实现的行为的示例。使用super时如果未使用super则无法获得什么行为?

例如,如果这是代码:

class Foo < ActiveRecord::Base
  def update_attributes(attributes)
    if super(attributes)
      MyMailer.deliver_notification_email
    end
  end
end

...然后我认为有趣的相关行为是,只有在没有验证错误的情况下才会传递电子邮件(因为这会导致super返回true而不是false)。所以,我可能会这样说:

describe Foo do
  describe "#update_attributes" do
    it 'sends an email when it passes validations' do
      record = Foo.new
      record.stub(:valid? => true)
      MyMailer.should_receive(:deliver_notification_email)
      record.update_attributes(:some => 'attribute')
    end

    it 'does not sent an email when it fails validations' do
      record = Foo.new
      record.stub(:valid? => false)
      MyMailer.should_receive(:deliver_notification_email)
      record.update_attributes(:some => 'attribute')
    end
  end
end

答案 1 :(得分:2)

尝试将should_recieve替换为should_receive