在Michael Hartl的教程第8章中进行测试失败

时间:2015-08-25 15:10:39

标签: ruby-on-rails ruby railstutorial.org

我正在研究Michael Hartl的Rails教程,我在第8.4.6章陷入困境,而Remember Test失败了。 我对下一步该做什么很困惑。

这是测试结果

 FAIL["test_login_with_remembering", UsersLoginTest, 2015-08-25 15:26:59 +0100]
 test_login_with_remembering#UsersLoginTest (1440512819.22s)
    Expected nil to not be nil.
    test/integration/users_login_test.rb:52:in `block in <class:UsersLoginTest>'

这是我的user_login_test.rb

require 'test_helper'

    class UsersLoginTest < ActionDispatch::IntegrationTest

      def setup
        @user = users(:microte)
      end

      test "login with invalid information" do
        get login_path
        assert_template "sessions/new"
        post login_path, session: { email: "", password: "" }
        assert_template "sessions/new"
        assert_not flash.empty?
        get root_path
        assert flash.empty?
      end

      test "login with valid information" do
        get login_path
        post login_path, session: { email: @user.email, password: 'microte' }
        assert_redirected_to @user
        follow_redirect!
        assert_template "users/show"
        assert_select "a[href=?]", login_path, count: 0
        assert_select "a[href=?]", logout_path
        assert_select "a[href=?]", user_path(@user)
      end

      test "login with valid information followed by logout" do
        get login_path
        post login_path, session: { email: @user.email, password: 'microte' }
        assert_redirected_to @user
        follow_redirect!
        assert_template "users/show"
        assert_select "a[href=?]", login_path, count: 0
        assert_select "a[href=?]", logout_path
        assert_select "a[href=?]", user_path(@user)
        delete logout_path
        assert_not is_logged_in?
        assert_redirected_to root_url
        # simulate a user clicking logout in a second window.
        delete logout_path
        follow_redirect!
        assert_select "a[href=?]", login_path
        assert_select "a[href=?]", logout_path, count: 0
        assert_select "a[href=?]", user_path(@user), count: 0
      end

        test "login with remembering" do
        log_in_as(@user, remember_me: '1')
        assert_not_nil cookies['remember_token'] #line 52
      end

      test "login without remembering" do
        log_in_as(@user, remember_me: '0')
        assert_nil cookies['remember_token']
      end
    end

我的session_controller.rb

class SessionsController < ApplicationController
      def new
      end

      def create
        user = User.find_by(email: params[:session][:email].downcase)
        if user && user.authenticate(params[:session][:password])
          log_in user
          params[:session][:remember_me] == '1' ? remember(user) : forget(user)

          redirect_to user
        else
          flash.now[:danger] = "Invalid e-mail/password combination"
          render "new"
        end
      end

      def destroy
        log_out if logged_in?
        redirect_to root_url
      end
    end

我的test_helper.rb

ENV['RAILS_ENV'] ||= 'test'
    require File.expand_path('../../config/environment', __FILE__)
    require 'rails/test_help'
    require "minitest/reporters"
    Minitest::Reporters.use!

    class ActiveSupport::TestCase
      # Setup all fixtures in test/fixtures/*.yml for all tests in alphabetical order.
      fixtures :all

      # Add more helper methods to be used by all tests here...

      # Returns true if a test user is logged in.
      def is_logged_in?
        !session[:user_id].nil?
      end

      # Log in a test user.
      def log_in_as(user, options = {})
        password = options[:password]     || 'password'
        remember_me = options[:remember_me]  || '1'
        if integration_test?
          post login_path, session: { email:        user.email, 
                                      password:     password,
                                      remember_me:  remember_me }
        else
          session[:user_id] = user.id
        end
      end

        private

        # Returns true inside an integration test.
        def integration_test?
          defined?(post_via_redirect)
        end
    end

users.yml里

microte:
      name: Lord Microte
      email: lord@microte.com
      password_digest: <%= User.digest('password') %>

如果有人可以提供帮助,我真的很感激。

4 个答案:

答案 0 :(得分:2)

我遇到了同样的问题,这是因为yml文件中的password_digest 你需要选择一个并承诺。

例如: 在yml文件中:

password_digest: <%= User.digest('example') %>

然后

在test_helper.rb

def log_in_as(user, options = {})
    password = options[:password]     || 'example'

和user_login_test.rb

post login_path, session: { email: @user.email, password: 'example' }

答案 1 :(得分:0)

一切看起来都是复杂的,所以我很欣赏你的挫败感。你能分享你的users.yml夹具吗?它是唯一涉及的其他部分,因为它是您定义用户&#34; microte&#34;的地方。 - 也许问题在那里?

答案 2 :(得分:0)

我和同一个问题在同一章。我已经尝试了很多方法来通过测试,奇怪的是cookie ['remember_token']仅在测试环境中为零,而在开发环境中一切正常(我可以通过检查它看到remember_token cookie)在浏览器上)。 无论如何,我完成了章节并开始练习(第二个),猜猜? 在@user中的current_user方法中将用户定义为实例变量(session_helper.rb)并使用assert_equal cookies['remember_token'], assigns(:user).remember_digest执行测试过程。

我不知道为什么在8.15的教程中列出的测试是绿色的,因为无论我在哪里看到我都找到了同样问题的人。

希望这会有所帮助。

答案 3 :(得分:0)

遇到了同样的问题并再次浏览了这一章 - 并在我的app / helpers / sessions_helper.rb中找到

def remember(user)
    user.remember
    cookies.permanent.signed[:user_id] = user.id
    cookies.permanent.signed[:remember_token] = user.remember_token
end

而不是:

def remember(user)
    user.remember
    cookies.permanent.signed[:user_id] = user.id
    **cookies.permanent[:remember_token] = user.remember_token**
end

希望有所帮助!