2011-02-03 6 views
6

私はRspecが新しく、ユーザープロファイルのテストを設定しようとしています。プロファイルbelongs_to User。Rspec Mocking:ActiveRecord :: AssociationTypeMismatch

ユーザーモデルを使用して動作する第三者サイトとのAPI統合がありますが、そのAPIリンクの情報の一部はプロファイルに含まれているため、プロファイルに「after_update」フィルタがあります親ユーザーが保存すると、APIの更新がトリガーされます。

私はこれのためのテストを書こうとしていますが、私はActiveRecord :: AssociationTypeMismatchを取得しています。理由は私が偽のユーザーを使用しているが、私はプロファイルが更新されたときにそれを送信しようとしている:ユーザーに保存します。さらに、Userモデルには電子メールの確認プロセスがあり、そのAPI呼び出しで作成プロセスが呼び出されるため、実際にテストするためにユーザーを作成することは実際には理想的ではありません。

it "should save the parent user object after it is saved" do 
    user = double('user', :save => true) 
    profile = Profile.create(:first_name => 'John', :last_name => 'Doe') 
    profile.user = user 

    user.should_receive(:save) 
end 

はそう、はっきりActiveRecordのエラーは、実際のユーザーが関連することを期待したプロファイルでモックユーザーを関連付けるために試みることによって引き起こされている:

は、ここに私のテストです。

私の質問は、レールテストを書く上でこのような問題をどうやって回避するのですか?このテストでは、プロファイルの呼び出しを確認するだけです:親のユーザーに保存します。これを行うよりスマートな方法、またはActiveRecordエラーの回避策はありますか?

ありがとうございます!

+0

個人的に私はfactory_girlのようなものを使って既に確認済みのUserオブジェクトを作成し、その上に 'save' expectationを設定します。電子メールプロセスを経由せずに確認済みのユーザーを偽装することはできませんか?これは、コード設計に関していくつかの警報を発する。 –

+0

まあ、あなたの提案は、私が行かなければならない方法だった。私は、コントローラがテスト環境でその呼び出しをトリガーしないように指示することで呼びたくないAPIを分離することができました。これにより、Factoryオブジェクトを期待どおりに処理できるようになりました。しかし、私はAPIのアクションをテスト統合に戻さなければならなかったので、結局のところ私はこのアプローチを断念し、APIのサンドボックス環境に定期的にクリアする必要がある迷惑データがいっぱいになるようにしました。私が好むものではありませんが、それは私にテストを可能にします。 – Andrew

答えて

3

私はこの問題を回避することができた唯一の方法ではなく、モックの工場のユーザーを使用することがわかりました。それはイライラしますが、2つのActiveRecordモデル間のコールバックをテストするときは、実際のモデルを使用する必要があります。そうしないとセーブコールが失敗し、ライフサイクルは起こらず、コールバックはテストできません。

+0

コールバックを関連するモデル仕様でテストするべきではありませんか? – Starkers

11

あなたはこのためmock_modelを使用することができるはずです。

it "should save the parent user object after it is saved" do 
    user = mock_model(User) 
    user.should_receive(:save).and_return(true) 
    profile = Profile.create(:first_name => 'John', :last_name => 'Doe') 
    profile.user = user 
end 
+0

私はこれを試して、それは動作しませんでした。 – Andrew

+2

具体的には何ですか? – zetetic

+0

それは動作します。ありがとう! –

関連する問題