我有一个类似的方法:
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
创建期间模拟数据库崩溃,并测试reservation
和reserved_hour
是否成功销毁。有没有办法在不扩展我的create
方法的情况下执行此操作仅用于测试目的?我可以通过运行ActiveRecord::Base.remove_connection
来模拟所有三种情况的崩溃,但我不知道如何通过一次崩溃来测试该情况。
答案 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
业务,您的交易将被回滚。