【问题标题】:Rspec testing methods in transaction事务中的 Rspec 测试方法
【发布时间】:2016-01-15 03:43:34
【问题描述】:

我正在尝试在事务中执行两件事,但我不确定应该如何在 rspec 中对其进行测试。我的代码如下所示:

实施:

    def method
      begin
        ActiveRecord::Base.transaction do
          ...some implementation...
          model1.save!
          model2.save!
        end
      rescue => e
          exception_info = {:class => e.class, :message => e.message, :backtrace => e.backtrace}
          @logger.warn("Error. Rolling back.", :exception => exception_info)
      end
    end

测试:

it "model1 object is not created if model2 fails to save" do
  Model1.any_instance.should_receive(:save).and_raise("model1 save error!!")
  method
  Model2.all.should == []
end

it "" do
  Model2.any_instance.should_receive(:save).and_raise("model2 save error!!")
  method
  Model1.all.should == []
end

我希望两个模型都保存或不保存。我的 rspec 测试检查了这两种情况,但我不断收到错误。如果我将 (:requires_new => true) 添加到事务中,它会起作用。我认为它是用于嵌套事务的,而不是这样的。我错过了什么吗?

【问题讨论】:

  • 你遇到了什么错误?
  • model2 在 model1 爆炸时创建(引发错误)
  • 您的测试将始终失败,因为如果没有记录,Model.all 将返回 []
  • 另外,您使用的是database_cleaner gem 吗?这将所有内容都包含在事务中。
  • 是的,这只是伪代码。我的代码做的远不止这些。我会更新测试。我没有使用 database_cleaner gem。

标签: ruby-on-rails activerecord rspec


【解决方案1】:

ActiveRecord 事务仅在引发异常时回滚。否则,它们会保留成功创建的任何记录。

在您的情况下,您想使用save! 而不是save 来中断事务。这将引发您需要救援和处理的ActiveRecord::RecordInvalid 异常。

begin
  ActiveRecord::Base.transaction do
    ...some implementation...
    model1.save!
    model2.save!
  end
rescue ActiveRecord::RecordInvalid
end

【讨论】:

  • 我有这个,还是不行:rescue => e exception_info = {:class=> e.class, :message => e.message, :backtrace => e.backtrace} @ logger.warn("错误。正在回滚。", :exception => exception_info)
  • @AmirShadaabMohammed 我忘记了 bang 版本,你添加了吗?
  • @AmirShadaabMohammed:您是否测试过控制台中的功能?如果一个模型保存失败,它会回滚吗?
  • 我发现了问题,我会尽快发布解决方案
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-12
  • 2012-06-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多