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_userApplicationController类上存根方法,而不是该类的实例。

我建议在该类的实例上(正确地)其存根,但您的测试似乎是集成测试而不是控制器测试。

然后我会做的是正如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

它看起来不像控制器测试。它看起来更像是模拟浏览器的 rspec-rails 请求规范。所以刺伤控制器不起作用,你必须模拟登录(像这样)

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

或手动将 user_id 添加到会话中。

另一方面,如果您想单独测试控制器,您的测试应该如下所示:

get 'index'
response.should be_success
于 2012-06-09T22:18:52.997 回答
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 回答