2013-08-23 17 views
1

我正在通过Michael Hartl的Rails教程。我下载了源代码samle_app_rails_4。 然后我添加一个测试用于注销用户,它在我的浏览器中正常工作,但是在Rspec中,它失败。我没有改变任何源代码,但将其添加到user_pages_spec.rbRails教程为用户注销添加测试但失败

require 'spec_helper' 
describe "User pages" do 

    describe "sign out" do 
    let(:user) { FactoryGirl.create(:user) } 
    before :each do 
     sign_in user 
    end 

    it "should sign out a user" do 
     delete signout_path 
     expect(page).to have_content("Sign in") 
    end 
    end 
end 

sign_in方法在spec/support/utilities.rb

include ApplicationHelper 

def sign_in(user, options={}) 
    if options[:no_capybara] 
    # Sign in when not using Capybara as well. 
    remember_token = User.new_remember_token 
    cookies[:remember_token] = remember_token 
    user.update_attribute(:remember_token, User.encrypt(remember_token)) 
    else 
    visit signin_path 
    fill_in "Email", with: user.email 
    fill_in "Password", with: user.password 
    click_button "Sign in" 
    end 
end 

定义的sessions_controller.rb是这样的(我忽略了这里创建行动。)

class SessionsController < ApplicationController 
    def new 
    end 

    def destroy 
    sign_out 
    redirect_to root_url 
    end 
end 

而且sessions_helper.rb是这样的:

module SessionsHelper 

    def sign_in(user) 
    remember_token = User.new_remember_token 
    cookies.permanent[:remember_token] = remember_token 
    user.update_attribute(:remember_token, User.encrypt(remember_token)) 
    self.current_user = user 
    end 

    def signed_in? 
    !current_user.nil? 
    end 

    def current_user=(user) 
    @current_user = user 
    end 

    def current_user 
    remember_token = User.encrypt(cookies[:remember_token]) 
    @current_user ||= User.find_by(remember_token: remember_token) 
    end 

    def current_user?(user) 
    user == current_user 
    end 

    def sign_out 
    self.current_user = nil 
    cookies.delete(:remember_token) 
    end 
end 

我已经尝试了多种解决方案,张贴的问题在github上,这Cookies do not persist in Rspec on rails 3.1

我也经历这些问题,但没有什么是有帮助的。 https://stackoverflow.com/questions/tagged/railstutorial.org

我甚至升级了我的rspec和水豚宝石。也许我的测试文件有问题? delete signout_path不适合注销用户吗? 我发现它在示例应用程序中很奇怪,因为用户已经登录,他仍然可以访问signin_path和signup_path。

希望有人能帮助我,非常感谢!

回答

1

您在示例中访问的page变量仅适用于使用水豚方法,如visitclick。通过直接发出HTTP delete操作,您绕过了水豚以及page变量的设置。

您可以使用例如访问响应正文response.body,但要注意,教程演示使用不同的要求规范和水豚的click方法在http://ruby.railstutorial.org/book/ruby-on-rails-tutorial#code-signout_test签出的考验。

+0

这对我有效。但是我也发现它在authentication_pages_spec.rb中使用'put user_path(user)}',这是通过curl之类的东西访问的,对吗?所以如果我想正常注销用户,我应该使用点击注销链接,得到它。十分感谢! – whyisyoung

+0

我没有发现任何'put'的用法,但是我确实使用了'post'和'patch'。看起来Michael在这个请求规范中包含了控制器示例。我不确定这是为什么。也许他希望保持身份验证和授权范例彼此接近。至于使用'curl',我不确定你的意思。在我看到的例子中,他只是检查'response'的值。 –

+0

对不起,'put'是Rails 3.2,我的意思是'patch user_path(user)'。是的,他想检查未登录的用户无法更新用户,谢谢你的回答。 – whyisyoung

0

当我阅读代码,SessionsController#destroy重定向到static_pages#home不包含字符串“登录”

+1

登录链接位于标题中,位于'app/views/layouts/_header.html.erb' –

+0

D'oh!你是对的。 – Fred

0
在规范

您重定向signout用户后root_url,所以你应该有串“登录”在root_url中,只需将例如<h1>Sign in</h1>添加到您的root_url视图中,并且它将被传递,如果您的根网址不包含要登录的表单,在这种情况下,您应该重定向到signin_path(将包含字符串“Sign in“)

+0

正如Peter所说,登录链接位于标头中:'app/views/layouts/_header.html.erb'。 – whyisyoung