AuthLogicコントローラーの仕様でモックモデルを使用するにはどうすればよいですか?
-
06-07-2019 - |
質問
フィクスチャを使用せずに(モックモデルを使用する代わりに)コントローラの仕様を記述しようとしています。このコントローラーでは、ユーザーがログインする必要があります。このために、 AuthLogic を使用し、著者の推奨事項。
describe UsersController do
def mock_user(stubs={})
@mock_user ||= mock_model(User, stubs)
end
context 'when logged in' do
before { activate_authlogic }
it "exposes the logged-in user as @user in response to GET (show)" do
UserSession.create(mock_user)
...
end
...
end
...
end
これらの例はすべて、 UserSession.create(...)
の行で失敗し、次の影響を報告しています。
Mock 'User_1005' received unexpected message :changed? with (no args)
これを解決する方法がわかりません。 :changedでモックしていますか? => false
は適切ですか?
解決
Iainは AuthLogicでモックオブジェクトを使用するソリューションを投稿しました。言い換えると、次のヘルパーは spec_helpers.rb
に入ります:
def current_user(stubs = {})
@current_user ||= mock_model(User, stubs)
end
def user_session(stubs = {}, user_stubs = {})
@current_user_session ||= mock_model(UserSession, {:user => current_user(user_stubs)}.merge(stubs))
end
def login(session_stubs = {}, user_stubs = {})
UserSession.stub!(:find).and_return(user_session(session_stubs, user_stubs))
end
def logout
@user_session = nil
end
これを仕様に組み込みましたが、私が望んでいたとおりに機能することがわかりました。ログインしているユーザーのモックモデルを利用する作業コントローラーの仕様があるので、ユーザーにフィールドを追加しても、すべてが壊れることはありません。これを仕様に実装するIainの例は次のとおりです。
describe SecretsController do
before { login }
it "should be very very secret!"
end
PS私は自分の質問に答えるのは嫌いですが、これは私が探していた答えです。十分に早く見つけられませんでした。
他のヒント
Authlogicは、レコードがアクティブなレコードインスタンスのように動作することを期待しています。実際のインスタンスまたはモックを使用できますが、モック/スタブを使用する場合は、Authlogicが必要とするすべてのメソッドに確実に応答する必要があります。
モックの代わりに実際のアクティブなレコードオブジェクトを使用することをお勧めします。フィクスチャを使用したくない場合は、ファクトリを使用できます。
最後のオプションは、任意のメソッドに応答するモックを渡すことです(これはmethod_missingで簡単に実現できます)。このソリューションの問題は、どの値が特定のメソッド呼び出しを返すべきかを事前に知らないことです。
はい、falseを渡すことができますが、これは実際には解決策ではありません。すべてのAuthlogicリクエストに応答するモックオブジェクトが見つかるまで、デフォルト値を手動で試行/追加する必要があります。ただし、これは、スタブへの未応答の呼び出しを修正するために、内部変更のために常にauthlogicに従う必要があります。
Rails 3では、AuthLogicのUserSessionはActiveRecord :: Baseのインスタンスではないため、このUserSessionのモックは機能しません。私のために働く修正:
class UserSession < Authlogic::Session::Base
extend ActiveModel::Naming
end
authlogicオブジェクトのモックは困難であることがわかり、最終的にモックをあきらめました。代わりに、 object daddy を使用したジェネレーターアプローチを使用しています。私の機能テストは今ではずっと幸せです。ところで、 shoulda + object_daddyは絶対に揺れ動きます。 Shouldaのトランザクションコンテキストにより、テストデータベースがクリーンな状態に保たれ、最初に単純なactiverecordオブジェクトをモックする必要がなくなります。