Testing after_commit with RSpec and mocking Testing after_commit with RSpec and mocking ruby ruby

Testing after_commit with RSpec and mocking


I thought Mihail Davydenkov's comment deserved to be an answer:

You can also use subject.run_callbacks(:commit).

Also note that this issue (commit callbacks not getting called in transactional tests) should be fixed in rails 5.0+ so you may wish to make a note to remove any workarounds you may use in the meantime when you upgrade. See: https://github.com/rails/rails/pull/18458


Try to use test_after_commit gem

or add following code in spec/support/helpers/test_after_commit.rb - Gist


I'm using DatabaseCleaner, with a configuration where I can easily switch between transaction and truncation, where the former is preferred, because of speed, but where the latter can be used for testing callbacks.

RSpec before and after handlers work with scopes, so if you want to make truncation a scope, define a before handler;

config.before(:each, truncate: true) do  DatabaseCleaner.strategy = :truncationend

And now to use this configuration for a describe, context or it block, you should declare it like:

describe "callbacks", truncate: true do   # all specs within this block will be using the truncation strategy  describe "#save" do    it "should trigger my callback" do      expect(lead).to receive(:send_to_SPL)      lead = Lead.create(init_hash)    end  endend

Complete hook configuration: (store in spec/support/database_cleaner.rb)

RSpec.configure do |config|  config.before(:suite) do    DatabaseCleaner.clean_with(:truncation)  end  config.before(:each) do    DatabaseCleaner.strategy = :transaction  end  config.before(:each, truncate: true) do    DatabaseCleaner.strategy = :truncation  end  config.before(:each) do    DatabaseCleaner.start  end  config.append_after(:each) do    DatabaseCleaner.clean  endend