仅当模型中存在PUTS时,Rspec测试才会通过

时间:2016-09-21 08:15:32

标签: ruby-on-rails ruby rspec callback

puts声明必须具有我在这里看不到的某种奇怪的效果......

我有一个Order型号。模型上有一个回调,其中回调要求模型完全提交;即,我需要使用after_commit。但是,回调是否应该运行的决定因素需要ActiveRecord::Dirty因此需要before_save(或after_save,但我使用before_save基于其他一些非必要的信息)。

我把两者结合起来了:

class Order
  # not stored in DB, used solely to help the before_save to after_commit transition
  attr_accessor :calendar_alert_type, :twilio_alerter

  before_save
    if self.calendar_alert_type.nil?
      if self.new_record?
        self.calendar_alert_type = "create, both"
      elsif self.email_changed?
        self.calendar_alert_type = "update, both" 
      elsif self.delivery_start_changed? || self.delivery_end_changed? || (type_logistics_attributes_modified.include? "delivery")
        self.calendar_alert_type = "update, start"
      elsif self.pickup_start_changed? || self.pickup_end_changed? || (type_logistics_attributes_modified.include? "pickup")
        self.calendar_alert_type = "update, end"
      end
    end

    puts "whatever"
  end

  after_commit do
    if self.calendar_alert_type.present?
      calendar_alert(self.calendar_alert_type) 
    end
  end
end

def calendar_alert(alert_info)
  puts "whatever"
  alert_type = alert_info.split(",")[0].strip
  start_or_end = alert_info.split(",")[1].strip
  if start_or_end == "both"
    ["start","end"].each do |which_end|
      Calendar.send(alert_type, which_end, self.id)
    end
  else
    Calendar.send(alert_type, start_or_end, self.id)
  end
end

所有私有方法和ActiveRecord::Dirty语句都正常工作。这是一个规范的例子:

it "email is updated" do
  Calendar.should_receive(:send).with("update", "start", @order.id).ordered
  Calendar.should_receive(:send).with("update", "end", @order.id).ordered
  find("[name='email']").set("nes@example.com")
  find(".submit-changes").click
  sleep(1)
end

it "phone is updated" do
  ... #same format as above
end

如果存在puts个语句,则只有上述所有规范才会传递。我觉得我在这里遗漏了一些非常基本的东西,只是不能把手指放在上面。这是非常奇怪的,因为puts语句吐出随机文本...

*注意,我完全知道should_receive应该是expect_to_receive并且我不应该使用睡眠,并且对功能测试的期望模拟效果不佳。努力将规范与错误的代码日分开更新,但这些不应该导致此问题...(随意纠正我)

1 个答案:

答案 0 :(得分:0)

此行为取决于您的Rails版本。在Rails 5之前,您可以返回除false值之外的任何内容以继续运行。 false将中止before_*回调链。 puts 'whatever'返回零。所以每件事都有效。您的if阻止似乎返回falsecalendar_alert_type的自定义实施?)。在这种情况下,链条是固定的。

使用Rails 5,您必须throw(:abort)才能停止回调处理。

相关问题