web-dev-qa-db-ja.com

リクエスト仕様でApplicationControllerメソッドをスタブする方法

Rspec/capybaraリクエスト仕様のcurrent_userメソッドの応答をスタブする必要があります。メソッドはApplicationControllerで定義されており、helper_methodを使用しています。メソッドは単にユーザーIDを返すだけです。テスト内では、このメソッドが毎回同じユーザーIDを返すようにします。

または、仕様でsession[:user_id]を設定することで問題を解決できます(これはcurrent_userが返すものです)...

これらのいずれかは可能ですか?

編集:

ここに私が持っているものがあります(動作していません。通常のcurrent_userメソッドを実行するだけです)。

require 'spec_helper'

describe "Login" do

   before(:each) do
     ApplicationController.stub(:current_user).and_return(User.first)
   end

  it "logs in" do
    visit '/'
    page.should have_content("Hey there user!")
  end

end

動作していません:

require 'spec_helper'

describe "Login" do

  before(:each) do
    @mock_controller = mock("ApplicationController") 
    @mock_controller.stub(:current_user).and_return(User.first)
  end

  it "logs in" do
    visit '/'
    page.should have_content("Hey there user!")
  end

end
59
Matt Fordham

skaleeはコメントで正しい答えを提供したようです。

スタブしようとしているメソッドがクラスメソッドではなく、インスタンスメソッド(ほとんどの場合)である場合、以下を使用する必要があります。

ApplicationController.any_instance.stub(:current_user)

58
fess .

基本フォームの例をいくつか示します。

_controller.stub(:action_name).and_raise([some error])
controller.stub(:action_name).and_return([some value])
_

あなたの特定の場合、適切な形式は次のようになると思います。

_controller.stub(:current_user).and_return([your user object/id])
_

これが私が取り組んでいるプロジェクトの完全な実例です:

_describe PortalsController do

  it "if an ActionController::InvalidAuthenticityToken is raised the user should be redirected to login" do
    controller.stub(:index).and_raise(ActionController::InvalidAuthenticityToken)
    get :index
    flash[:notice].should eql("Your session has expired.")
    response.should redirect_to(portals_path)
  end

end
_

私の完全な例を説明すると、基本的にこれが行うことは、アプリ内のどこかで_ActionController::InvalidAuthenticityToken_エラーが発生したとき、フラッシュメッセージが表示され、ユーザーが_portals_controller#index_アクションにリダイレクトされることを確認することですこれらのフォームを使用して、特定の値をスタブアウトして返したり、発生する特定のエラーのインスタンスをテストしたりできます。いくつかの.stub(:action_name).and_[do_something_interesting]()メソッドを使用できます。


更新(コードを追加した後):コメントごとに、コードを次のように変更します。

_require 'spec_helper'

describe "Login" do

   before(:each) do
      @mock_controller = mock("ApplicationController") 
      @mock_controller.stub(:current_user).and_return(User.first)
   end

  it "logs in" do
    visit '/'
    page.should have_content("Hey there user!")
  end

end
_
14
jefflunt

これは私のために働き、@current_userテストで使用する変数。

次のようなヘルパーがあります。

def bypass_authentication
  current_user = FactoryGirl.create(:user)

  ApplicationController.send(:alias_method, :old_current_user, :current_user)
  ApplicationController.send(:define_method, :current_user) do 
    current_user
  end
  @current_user = current_user
end

def restore_authentication
  ApplicationController.send(:alias_method, :current_user, :old_current_user)
end

そして、私のリクエスト仕様で、私は呼び出します:

before(:each){bypass_authentication}
after(:each){restore_authentication}
3
iHiD

Ivarを設定するアプリケーションコントローラーメソッドをスタブする必要がある他の人(そして、それをしてはいけない理由について果てしない手探りで地に陥った)は、2013年10月頃のRspecの風味で機能する方法です。

before(:each) do
  campaign = Campaign.create!
  ApplicationController.any_instance.stub(:load_campaign_singleton)
  controller.instance_eval{@campaign = campaign}
  @campaign = campaign
end

メソッドをスタブ化して何もせず、rspecのコントローラーインスタンスにivarを設定し、@ campaignとしてテストで使用できるようにします。

2

Rspec 3+の場合、新しいAPIは次のとおりです。

コントローラーテストの場合、ニースとショート:

allow(controller).to receive(:current_user).and_return(@user)

または、ApplicationControllerのすべてのインスタンスに対して:

allow_any_instance_of(ApplicationController).to receive(:current_user).and_return(@user)
1
Sbbs

提供された応答はどれも私にとってはうまくいきませんでした。 @ matt-fordamの元の投稿のように、コントローラーの仕様ではなく、リクエストの仕様があります。このテストは、コントローラーを起動せずにビューをレンダリングするだけです。

これで説明されているようにビューのメソッドをスタブすることでこれを解決しました other SO post

view.stub(:current_user).and_return(etc)
1
jwadsack