在控制器测试中,我想测试一下,登录后,控制器会将请求呈现为罚款,否则如果没有登录,则会重定向到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
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
答案 0 :(得分: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
答案 1 :(得分:0)
我会看http://ruby.railstutorial.org/chapters/sign-in-sign-out#sec:a_working_sign_in_method。
作者描述了如何编写sign_in方法并在rspec测试中使用它。
答案 2 :(得分:0)
它看起来不像控制器测试。它看起来更像是模拟浏览器的rspec-rails请求规范。所以刺伤控制器不起作用,你必须模拟登录(类似这样)
visit sign_in
fill_in 'username', :with => 'username'
...
或手动将user_id添加到会话。
另一方面,如果你想要独立测试控制器,你的测试应该是这样的:
get 'index'
response.should be_success