使用RSpec和Factory Girl测试before_save

Der*_*ill 1 rspec ruby-on-rails factory-bot

我正在使用before_save调用来更新属于特定主服务器的所有记录.两者都有一个名为item_id的字段:

class Master < ActiveRecord::Base
  has_many :records
  before_save :update_records
  def update_records
    self.records.find_each do |r|
      r.item_id = self.item_id
      r.save
    end
  end
end

class Record < ActiveRecord::Base
end
Run Code Online (Sandbox Code Playgroud)

这是按照预期的方式工作(暂时搁置一下,做这样的事情是否是个好主意).但是我无法通过RSpec测试.这是我试过的:

describe Master do
  describe 'before_save' do
    it 'updates records belonging to it' do
      master = FactoryGirl.create(:master, item_id: 1)
      record = FactoryGirl.create(:record, master_id: master.id, item_id: 1)
      master.item_id = 2
      master.save
      record.item_id.should == 2
    end
  end
end
Run Code Online (Sandbox Code Playgroud)

原因很有趣.该模型在Record模型的第二个实例上工作,该模型成功保存,但不会返回到规范:

"MASTER - CREATED IN SPEC"
#<Master:0x007fd0ed55ec20> {
    :id => 26,
    :item_id => 1,
}
"RECORD - CREATED IN SPEC"
#<Record:0x007fd0ea157e40> {
    :id => 16,
    :item_id => 1,
    :master_id => 26,
}
"RECORD - AFTER SAVE IN MODEL"
#<Record:0x007fd0ed2f9a70> {
    :id => 16,
    :item_id => 2,
    :master_id => 26,
}
"MASTER - UPDATED IN SPEC"
#<Master:0x007fd0ed55ec20> {
    :id => 26,
    :item_id => 2,
}
"RECORD - FINAL IN SPEC"
#<Record:0x007fd0ea157e40> {
    :id => 16,
    :item_id => 1,
    :master_id => 26,
}
Run Code Online (Sandbox Code Playgroud)

你知道吗:

  • 为什么会这样?
  • 我怎么能通过这个规范?

Mor*_*ori 5

看起来您的记录只显示旧数据,需要刷新.尝试:

record.reload.item_id.should == 2
Run Code Online (Sandbox Code Playgroud)