AuthLogicコントローラーの仕様でモックモデルを使用するにはどうすればよいですか?

StackOverflow https://stackoverflow.com/questions/1025594

質問

フィクスチャを使用せずに(モックモデルを使用する代わりに)コントローラの仕様を記述しようとしています。このコントローラーでは、ユーザーがログインする必要があります。このために、 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オブジェクトをモックする必要がなくなります。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top