测试关联模型中的存根回调

时间:2011-10-10 08:30:08

标签: ruby-on-rails ruby rspec

我有两个模型,通过简单的一对多关系链接。

class Device
  has_many :events

  def notify!
    (...)
  end
end

class Event
  after_create :notify_device
  belongs_to :device

  private

  def notify_device
    device.notify!
  end
end

Device#notify!方法必须在测试中存根,因为在正常流程中它会触发与通过RS-232链接的设备的通信,这显然可能在测试环境中不可用(更不用说它不应该被通知在测试中。)

我试图在FactoryGirl创建的should_receive对象上设置device期望值,但device类中使用的Event方法返回不同的对象,但不知道期待。

如何编写rspec测试来测试在适当的设备上调用#notify!的事实?

2 个答案:

答案 0 :(得分:0)

我无法看到如何期望给定AR记录的消息。您可以将此功能添加到rspec,也可以添加一些记录器来通知!方法:

class Device

  def notify!(event)
    logger "Device with id '{self.id}' has been notified by event '#{event}'"
  end
end

在我看来,这样的记录器在生产中可能很有用,但在测试记录时使用一些模拟,你可以交换记录器来使用对象,你可以在测试中轻松检查并检查来自通知的消息。

答案 1 :(得分:0)

如果测试中只有一个设备,则使用any_instance应该没问题(因为应该编写好的隔离测试)。

或者另一种选择是在Device而不是Event上使用回调:

class Device < ActiveRecord::Base
  has_many :events, :after_add => :notify!

  def notify!
    ...
  end
end

这应该更容易设定期望:

device = Device.new
device.should_receive(:notify!)
device.events << Event.create!

我刚想到的另一个选项(但尚未尝试过)是将活动记录用于在事件创建期间获取设备的方法存根。下面我猜它只是Device.find(device.id)但它可能是其他东西。

device = Factory(:device)
device.should_receive(:notify!)
Device.stub(:find).with(device.id) { device }
Event.create!(:device => device)