Rspec should_receive让我难过

时间:2014-03-10 14:53:13

标签: ruby-on-rails rspec

我需要测试是否由于调用类方法而在特定实例上调用实例方法。类似的东西:

class Dog < ActiveRecord::Base
  def self.roll_trained
    Dog.all.each { |d| d.rollover if d.trained? }
  end

  def rollover
    # rollover and stuff
  end
  def trained?
    self.trained == true
  end
end

我写了一个测试:

describe 'Dog.roll_trained' do
  it 'rolls trained dogs' do
    dog_1 = Dog.create(trained: true)
    dog_1.should_receive(:rollover)
    Dog.roll_trained
  end
end

我以为我做对了,但测试失败了。我在这里做错了什么?

1 个答案:

答案 0 :(得分:1)

这里的问题是dog_1和在Dog.each上循环的实例不是同一个实例。 这是因为当您执行Dog.each时,ActiveRecord会为数据库中的同一行(dog_1)生成不同的实例

我写了一篇关于此的博文,你可以在这里阅读:ActiveRecord and In-Memory Object State

一个解决方案是将Dog.all - Dog.stub(all: [dog_1])

存根

另一个解决方案是将trained属性保存到数据库,然后针对数据库进行规范:dog_1.reload.trained.should be_true