[rspec-users] Issue when testing ActiveRecord after_commit callbacks

David Chelimsky dchelimsky at gmail.com
Fri Jun 29 01:48:47 UTC 2012

On Thu, Jun 28, 2012 at 2:11 PM, Dennis Kuczynski
<dennis.kuczynski at gmail.com> wrote:
> In an ActiveRecord model, I have an after_commit callback (:enqueue_job)
> which places a job on my background processing queue (Sidekiq)
> To test that the callback was firing when the database transaction
> was committed, I was using:
> object.should_receive(:enqueue_job) #should pass
> Which seems to work.  However, to test that the test was valid, I attempted
> object.should_not_receive(:enqueue_job) #should fail
> But this did not fail.
> I tracked this down to ActiveRecord's
> DatabaseStatements' commit_transaction_records method, which ends up eating
> the RSpec Negative Method Expectation Exception (which fails fast)
> https://github.com/rails/rails/blob/3-2-stable/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb
> If the negative method expectation did not fail fast, the test would
> probably work, but is there a better pattern for testing after_commit logic?
> (This was with rspec-mocks 2.10.1.  use_transactional_fixtures was turned
> off to enable the callback.)
> Thanks,
> Dennis

Nice work finding the source of the problem. I guess you could do
something like this:

received = false
obj.stub(:enqueue_job) do |*|
  received = true
# ...
received.should be_true

It ain't pretty, but it should work (should fail properly if you say
`received.should be_false`).


More information about the rspec-users mailing list