我试图测试下面的模型的before_update回调.
车型/ option.rb:
class Option < ApplicationRecord belongs_to :activity has_many :suboptions, class_name: "Option", foreign_key: "option_id" belongs_to :parent, class_name: "Option", optional: true, foreign_key: "option_id" accepts_nested_attributes_for :suboptions, allow_destroy: true, reject_if: ->(attrs) { attrs['name'].blank? } validates :name, presence: true before_create :set_defaults before_update :set_updates def set_defaults self.suboptions.each do |sbp| sbp.activity_id = self.activity_id end end def set_updates suboptions.each do |child| child.activity_id = self.activity_id end end end
规格/型号/ option.rb:
require 'rails_helper' RSpec.describe Option, type: :model do describe "Callbacks" do it "before_create" do suboption = create(:option) option = create(:option, suboptions:[suboption]) option.run_callbacks(:create) {false} expect(option.suboptions.first.activity_id).to eq suboption.activity_id end it "before_update" do end end end
我成功测试了before_create回调(至少它给了我正确的结果).但我不知道如何测试before_update回调.有办法吗?
警告:这个答案是固执己见的.
测试行为,而不是实现.
回调是一个实现细节.不要直接测试.相反,假装您不知道模型如何在内部工作,并测试它的行为方式.
如果我正确地读取代码,可以这样描述行为:
更新选项时,每个子选项的activity_id都设置为选项的activity_id.
使用子选项创建选项.更新它,重新加载它,并检查每个activity_id的值是否正确.
这比嘲弄慢,但不那么脆弱.此外,测试更容易编写和维护.