1

コントローラーのテスト内で、ログインしたときにコントローラーがリクエストを正常にレンダリングするか、ログインしていない場合は login_path にリダイレクトするかをテストしたいと思います。

最初のテストは期待どおりに成功し、ユーザーがログインしていないため、リクエストは login_path にリダイレクトされます。ただし、無数の stub/stub_chain を試しましたが、ログインしているユーザーを偽造してページを正常にレンダリングするテストをまだ取得できません。

これを期待どおりに機能させるための指示をいただければ幸いです。

次のクラスとテストは、質問を簡潔にするための必要最小限のものです。

アプリケーションコントローラー

class ApplicationController < ActionController::Base
include SessionsHelper

  private
  def current_user
    @current_user ||= User.find(session[:user_id]) if session[:user_id]
  end
  helper_method :current_user
end

セッションヘルパー

 module SessionsHelper

  def logged_in?
    redirect_to login_path, :notice => "Please log in before continuing..." unless current_user
   end
end

アプリコントローラー

class AppsController < ApplicationController

  before_filter :logged_in?

  def index
    @title = "apps"
  end
end

apps_controller_spec.rb

require 'spec_helper'
describe AppsController do

  before do
    @user = FactoryGirl.create(:user)
  end

  describe "Visit apps_path" do
    it "should redirect to login path if not logged in" do
      visit apps_path
      current_path.should eq(login_path)
    end

    it "should get okay if logged in" do
      #stubs here, I've tried many variations but can't get any to work
      #stubbing the controller/ApplicationController/helper
      ApplicationController.stub(:current_user).and_return(@user)
      visit apps_path
      current_path.should eq(apps_path)
    end
  end
end
4

3 に答える 3

1

クラスのインスタンスではなく、クラスのメソッドcurrent_userをスタブ化しているため、これは機能しません。ApplicationController

そのクラスのインスタンスで(正しく)スタブすることお勧めしますが、テストはコントローラーテストではなく統合テストのようです。

代わりに私が行うことは、Art Shayderovが述べたように、認証されたユーザーが必要な場所にアクセスしようとする前に、ユーザーのサインイン アクションをエミュレートすることです。

visit sign_in_path
fill_in "Username", :with => "some_guy"
fill_in "Password", :with => "password"
click_button "Sign in"
page.should have_content("You have signed in successfully.")

私のアプリケーションでは、これをテスト用のヘルパー メソッドに移動しました。これは のファイルに配置されspec/support/authentication_helpers.rb、次のようになります。

module AuthenticationHelpers
  def sign_in_as!(user)
    visit sign_in_path
    fill_in "Username", :with => user.username
    fill_in "Password", :with => "password"
    click_button "Sign in"
    page.should have_content("You have signed in successfully.")
  end
end

RSpec.configure do |c|
  c.include AuthenticationHelpers, :type => :request
end

次に、リクエスト仕様で、特定のユーザーとしてサインインするメソッドを呼び出すだけです。

sign_in_as(user)

標準のコントローラー テストを使用してサインインする場合、Devise には既にこのためのヘルパーがあります。私は通常、これらを同じファイル ( spec/support/authentication_helpers.rb)に含めます。

 RSpec.configure do |c|
   c.include Devise::TestHelpers, :type => :controller
 end

次に、次のようなヘルパーを使用してサインインできます。

 before do
   sign_in(:user, user)
 end

 it "performs an action" do
   get :index
 end
于 2012-06-10T10:04:54.387 に答える
0

http://ruby.railstutorial.org/chapters/sign-in-sign-out#sec:a_working_sign_in_methodを見てください。

著者は、sign_in メソッドを作成し、rspec テストで使用する方法を説明しています。

于 2012-06-09T20:50:28.547 に答える
0

コントローラーのテストのようには見えません。ブラウザをシミュレートする rspec-rails リクエスト仕様に似ています。したがって、コントローラーを刺しても機能しません。サインインをシミュレートする必要があります(このようなもの)

visit sign_in
fill_in 'username', :with => 'username'
...

または手動で user_id をセッションに追加します。

一方、コントローラーを単独でテストする場合は、テストは次のようになります。

get 'index'
response.should be_success
于 2012-06-09T22:18:52.997 に答える