RSpec:当有更多数据库操作时,如何测试数据库失败

时间:2018-02-16 16:55:04

标签: ruby-on-rails database unit-testing rspec

我有一个类似的方法:

def create
  reservation = Reservation.create(params[:reservation_params])
  if reservation.valid?
    reserved_hour = ReservedHour.create(params[:reserved_hour_params])
    if reserved_hour.valid?
      notification = Notification.create(params[:notification])
      if !notification.valid?
        reservation.destroy
        reserved_hour.destroy
      end
    else
      reservation.destroy
    end
  end
end

现在我想用RSpec测试数据库失败案例。例如,我想在notification创建期间模拟数据库崩溃,并测试reservationreserved_hour是否成功销毁。有没有办法在不扩展我的create方法的情况下执行此操作仅用于测试目的?我可以通过运行ActiveRecord::Base.remove_connection来模拟所有三种情况的崩溃,但我不知道如何通过一次崩溃来测试该情况。

1 个答案:

答案 0 :(得分:0)

您的代码无法正常运行,因为您的所有.create调用都将始终返回某些内容(已保存的记录或未保存的记录)和您的if语句永远都是真的。

为什么不在transaction内使用.create!(如果create不成功会引发错误)。类似的东西:

def create
  ActiveRecord::Base.transaction do 
    begin
      Reservation.create!(params[:reservation_params])
      ReservedHour.create!(params[:reserved_hour_params])
      Notification.create!(params[:notification])
    rescue SomeError =>
      # do something with SomeError
    end
  end
end

这样,如果您遇到错误并且您不必完成所有.destroy业务,您的交易将被回滚。