简体   繁体   中英

Rspec testing methods in transaction

I am trying to execute two things inside a transaction and I'm not sure how I should test it in rspec. My code looks something like this:

Implementation:

    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

Tests:

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

I want both the models to be saved or none. My rspec tests check both the cases but I keep getting errors. If I add (:requires_new => true) to the transaction, it works. I thought it was meant for nested transactions, not something like this. Am I missing something?

ActiveRecord transactions only rollback if an exception is raised. Otherwise they persist whatever records were successfully created.

In your case, you want to use save! instead of save to interrupt the transaction. This will raise an ActiveRecord::RecordInvalid exception which you need to rescue and handle.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM