Ruby on Rails Michael Hartl 第 8.5 章测试失败 [英] Ruby on Rails Michael Hartl chapter 8.5 Test Fails
问题描述
我在另一次看到这个问题,其中 current_user 变量被定义了两次.我的代码中有同样的错误,但是删除 current_user 的第二个定义仍然无法解决我收到的错误消息.这是我在运行测试时收到的错误消息:
I've seen this question asked another time, in which the current_user variable was defined twice. I had the same error in my code, however removing the second definition of current_user still does not resolve the error message that I am receiving. This is the error message that I get when running my test:
1) Failure:
SessionsHelperTest#test_current_user_returns_right_user_when_session_is_nil [/home/ubuntu/workspace/sample_app/test/helpers/sessions_helper_test.rb:11]:
--- expected
+++ actual
@@ -1 +1 @@
-#<User id: 762146111, name: "Michael Example", email: "michael@example.com", created_at: "2016-06-06 19:15:21", updated_at: "2016-06-06 19:15:21", password_digest: "$2a$04$LkmHj4hHVcRoTuEH6icLs.E/GebaKaY2Y/TX5nqouIj...", remember_digest: nil>
+nil
<小时>
这是我的 session_helper 文件:
This is my sessions_helper file:
module SessionsHelper
#logs in the given user
def log_in(user)
session[:user_id] = user.id
end
#remembers a user in a persistent session
def remember(user)
user.remember
cookies.permanent.signed[:user_id] = user.id
cookies.permanent[:remember_token] = user.remember_token
end
#returns current logged in user
#def current_user
#@current_user ||= User.find_by(id: session[:user_id])
#end
#returns the user corresponding to the remember token
def current_user
if (user_id = session[:user_id])
@current_user ||= User.find_by(id: user_id)
elsif (user_id = cookies.signed[:user_id])
user = User.find_by(id: user_id)
if user && user.authenticated?(cookies[:remember_token])
log_in user
@current_user = user
end
end
end
def logged_in?
!current_user.nil?
end
def log_out
session.delete(:user_id)
@current_user = nil
end
#forgets a persistent session
def forget(user)
user.forget
cookies.delete(:user_id)
cookies.delete(:remember_token)
end
#logs out the current user
def log_out
forget(current_user)
session.delete(:user_id)
@current_user = nil
end
end
<小时>
这是我的 users_login_test 文件:
This is my users_login_test file:
require 'test_helper'
class UsersLoginTest < ActionDispatch::IntegrationTest
def setup
@user = users(:michael)
end
test "Login with invalid information followed by logout" do
get login_path
post login_path, session: { email: @user.email, password: 'password' }
assert is_logged_in?
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 logging out in a different 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']
end
test "login without remembering" do
log_in_as(@user, remember_me: '0')
assert_nil cookies['remember_token']
end
end
<小时>
这是我的 test_helper 文件:
This is my test_helper file:
ENV['RAILS_ENV'] ||= 'test'
require File.expand_path('../../config/environment', __FILE__)
require 'rails/test_help'
class ActiveSupport::TestCase
fixtures :all
# Returns true if a test user is logged in.
def is_logged_in?
!session[:user_id].nil?
end
# Logs 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 文件:
This is my users.yml file:
michael:
name: Michael Example
email: michael@example.com
password_digest: <%= User.digest('password') %>
<小时>
我真的不确定出了什么问题,但我想我只是错过了一些东西.任何帮助将非常感激!谢谢!
I'm really not sure whats going wrong, but I think I'm just missing something. Any help would be much appreciated! Thanks!
这是我的 user.rb 文件:
here is my user.rb file:
class User < ActiveRecord::Base
attr_accessor :remember_token
before_save { self.email = email.downcase }
validates :name, presence: true, length: { maximum: 50 }
VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i
validates :email, presence: true, length: { maximum: 255 },
format: { with: VALID_EMAIL_REGEX },
niqueness: { case_sensitive: false }
has_secure_password
validates :password, presence: true, length: { minimum: 6 }
#returns the digest of a given string
def User.digest(string)
cost = ActiveModel::SecurePassword.min_cost ? BCrypt::Engine::MIN_COST :
BCrypt::Engine.cost
BCrypt::Password.create(string, cost: cost)
end
#returns random token
def User.new_token
SecureRandom.urlsafe_base64
end
#remembers a user in the database for persistent sessions
def remember
self.remember_token = User.new_token
update_attribute(:remember_token, User.digest(remember_token))
end
#returms true if the given token matches the digest
def authenticated?(remember_token)
return false if remember_digest.nil?
BCrypt::Password.new(remember_digest).is_password? (remember_token)
end
#Forgets a user
def forget
update_attribute(:remember_digest, nil)
end
end
<小时>
session_helper_test.rb:
edit: sessions_helper_test.rb:
require 'test_helper'
class SessionsHelperTest < ActionView::TestCase
def setup
@user = users(:michael)
remember(@user)
end
test "current_user returns right user when session is nil" do
assert_equal @user, current_user
assert is_logged_in?
end
test "current_user returns nil when remember digest is wrong" do
@user.update_attribute(:remember_digest, User.digest(User.new_token))
assert_nil current_user
end
end
推荐答案
查看你的 session_helper.rb,#Logs out the current user
方法在文件中定义了两次.根据第 8 章中的本教程,为了运行绿色测试套件,您需要在文件中包含以下内容.
Looking at your sessions_helper.rb, the # Logs out the current user
method has been defined twice in the file. According to this tutorial in ch.8, in order to run the test suite green you need following content in your file.
我认为您在清单 8.39 中搞砸了,您只需要在 log_out 方法中添加一行即可.
I think you messed this up during listing 8.39 where you just need to add one line in the log_out method.
请在 sessions_helper.rb 中填写以下代码,您的测试将变为绿色.
Please fill up the following code in the sessions_helper.rb and your tests would go green.
module SessionsHelper
# Logs in the given user.
def log_in(user)
session[:user_id] = user.id
end
# Remembers a user in a persistent session.
def remember(user)
user.remember
cookies.permanent.signed[:user_id] = user.id
cookies.permanent[:remember_token] = user.remember_token
end
# Returns the user corresponding to the remember token cookie.
def current_user
if (user_id = session[:user_id])
@current_user ||= User.find_by(id: user_id)
elsif (user_id = cookies.signed[:user_id])
user = User.find_by(id: user_id)
if user && user.authenticated?(cookies[:remember_token])
log_in user
@current_user = user
end
end
end
# Returns true if the user is logged in, false otherwise.
def logged_in?
!current_user.nil?
end
# Forgets a persistent session.
def forget(user)
user.forget
cookies.delete(:user_id)
cookies.delete(:remember_token)
end
# Logs out the current user.
def log_out
forget(current_user)
session.delete(:user_id)
@current_user = nil
end
end
更新:同样在 app/models/user.rb 文件中,根据清单 8.45,您需要添加一行 return false if remember_digest.nil?
.所以 user.rb 文件应该如下所示.
Update:
Also in the app/models/user.rb file according to listing 8.45, you need to add a line return false if remember_digest.nil?
. So the user.rb file should be as following.
class User < ActiveRecord::Base
attr_accessor :remember_token
before_save { self.email = email.downcase }
validates :name, presence: true, length: { maximum: 50 }
VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i
validates :email, presence: true, length: { maximum: 255 },
format: { with: VALID_EMAIL_REGEX },
uniqueness: { case_sensitive: false }
has_secure_password
validates :password, presence: true, length: { minimum: 6 }
# Returns the hash digest of the given string.
def User.digest(string)
cost = ActiveModel::SecurePassword.min_cost ? BCrypt::Engine::MIN_COST :
BCrypt::Engine.cost
BCrypt::Password.create(string, cost: cost)
end
# Returns a random token.
def User.new_token
SecureRandom.urlsafe_base64
end
# Remembers a user in the database for use in persistent sessions.
def remember
self.remember_token = User.new_token
update_attribute(:remember_digest, User.digest(remember_token))
end
# Returns true if the given token matches the digest.
def authenticated?(remember_token)
return false if remember_digest.nil? #Add this line
BCrypt::Password.new(remember_digest).is_password?(remember_token)
end
# Forgets a user.
def forget
update_attribute(:remember_digest, nil)
end
end
如果您进一步遇到任何错误,请告诉我.
Please let me know if you face any error further.
这篇关于Ruby on Rails Michael Hartl 第 8.5 章测试失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!