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
skaleeはコメントで正しい答えを提供したようです。
スタブしようとしているメソッドがクラスメソッドではなく、インスタンスメソッド(ほとんどの場合)である場合、以下を使用する必要があります。
ApplicationController.any_instance.stub(:current_user)
基本フォームの例をいくつか示します。
_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
_
これは私のために働き、@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}
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としてテストで使用できるようにします。
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)
提供された応答はどれも私にとってはうまくいきませんでした。 @ matt-fordamの元の投稿のように、コントローラーの仕様ではなく、リクエストの仕様があります。このテストは、コントローラーを起動せずにビューをレンダリングするだけです。
これで説明されているようにビューのメソッドをスタブすることでこれを解決しました other SO post
view.stub(:current_user).and_return(etc)