答えて

25

これを回避する方法の1つは、commitコールバックを手動で開始することです。例:

describe SomeModel do 
    subject { ... } 

    context 'after_commit' do 
    after { subject.run_callbacks(:commit) } 

    it 'does something' do 
     subject.should_receive(:some_message) 
    end 
    end 
end 

少し遅れていますが、これが他の人に役立つことを願っています。

+0

素晴らしい提案。ありがとう。 –

+0

ありがとうございます。 – baash05

2

This Gist私を助け:ここ

は、私は上の問題が生じてきた最新のRSpecの/レールとレールのアプリです。

トランザクションフィクスチャを使用している場合でも、after_commitコールバックを発生させるためにMonkey-patches ActiveRecordを適用します。

これを新しいファイルをRails.root/spec/supportディレクトリに入れます。 。

Rails 3は自動的にテスト環境にロードします。

+0

これは私のために働いたが、私のスペックはunusably遅くなりました。今のところafter_saveを使用するように切り替えるつもりですが、すべてのケースでビジネスロジックと100%一致しないことが懸念されます。 –

5

database_cleanerを使用している場合は、このままでも実行されます。私はtest_after_commitの宝石を使用しています。それは私のためのトリックをするようです。私は下に配置database_cleanerの設定でこのような問題を解決私の場合は

+0

素晴らしい宝石!ありがとう! – Trip

8

config.use_transactional_fixtures = false 

config.before(:suite) do 
    DatabaseCleaner.strategy = :deletion 
    DatabaseCleaner.clean_with(:truncation) 
end 

config.before(:each) do 
    DatabaseCleaner.start 
end 

config.after(:each) do 
    DatabaseCleaner.clean 
end 

Testing after_commit/after_transaction with Rspec

+0

削除と切捨ての方針はトランザクションよりもはるかに遅いですが、これは実際にはほとんどの場合正しい答えです。 – averell

7

のおかげで、これは、上記の@ jamesdevarの回答に似ていますが、私は、コードブロックを追加することができませんでした、私は別のエントリを作る必要があります。

スペックスイート全体の戦略を変更する必要はありません。引き続き、:transactionをそのまま使用して、必要に応じて:deletionまたは:truncation(どちらも機能します)を使用してください。関連する仕様にフラグを追加するだけです。

あなたのスペックで、その後
config.use_transactional_fixtures = false 

config.before(:suite) do 
    # The :transaction strategy prevents :after_commit hooks from running 
    DatabaseCleaner.strategy = :transaction 
    DatabaseCleaner.clean_with(:truncation) 
end 

config.before(:each, :with_after_commit => true) do 
    DatabaseCleaner.strategy = :truncation 
end 

、:

describe "some test requiring after_commit hooks", :with_after_commit => true do 
+0

これは、オブジェクトの 'run_callbacks'に関係しない素晴らしい解決策であり、新しいgemをインストールする必要はありません! –

関連する問題