我在Michael Hartl的Ruby on Rails教程的8.3中的users_login_test中遇到了assert_select的问题。
这是测试:
test "login with valid 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
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
当我运行测试时,我得到1次失败:
FAIL["test_login_with_valid_information_followed_by_logout",
UsersLoginTest, 2016-01-20 09:51:41 +0000]
test_login_with_valid_information_followed_by_logout#UsersLoginTest (1453283501.83s)
Expected at least 1 element matching "a[href="/login"]", found 0..
Expected 0 to be >= 1.
test/integration/users_login_test.rb:31:in `block in <class:UsersLoginTest>'
这是我的会话控制器:
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
remember user
redirect_to user
else
flash.now[:danger] = 'Invalid email/password combination'
render 'new'
end
end
def destroy
log_out
redirect_to root_url
end
end
我的sessions_controller有一个重定向到root_url的destroy方法。我不知道问题是什么,但我知道我的测试失败,当我尝试注销时,我被重定向到主页但我仍然登录(在角落里我仍然有我的个人资料,设置和注销的链接)。
@Papouche Guinslyzinho你让我发表意见,帮助并摧毁控制器:
查看:header.html.rb
<header class="navbar navbar-fixed-top navbar-inverse">
<div class="containter">
<%= link_to "sample app", root_path, id: "logo" %>
<nav>
<ul class="nav navbar-nav navbar-right">
<li><%= link_to "Home", root_path %></li>
<li><%= link_to "Help", help_path %></li>
<%if logged_in? %>
<li><%= ;link_to "Users", "#"%></li>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown">
Account <b class="caret"></b>
</a>
<ul class="dropdown-menu">
<li><%= link_to "Profile", current_user %></li>
<li><%= link_to "Settings", "#" %></li>
<li class="divider"></li>
<li> <%= link_to "Log out", logout_path, method: "delete" %>
</li>
</ul>
</li>
<%else %>
<li><%= link_to "Log in", login_path %></li>
<%end %>
</ul>
</nav>
</div>
</header>
Sessions_helper:
module SessionsHelper
#logs in given user
def log_in(user)
session[:user_id] = user.id
end
#Remembers user in 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
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
forget(current_user)
session.delete(:user_id)
@current_user = nil
end
end
Sessions_controller:destroy
def destroy
log_out
redirect_to root_url
end
答案 0 :(得分:2)
首先尝试查看路线中是否有登录路径
rake routes | grep 'login'
你应该有这些:
login GET /login(.:format) sessions#new
POST /login(.:format) sessions#create
然后你的错误:
Expected at least 1 element matching "a[href="/login"]", found 0..
这说它在你的html页面中找不到<a href="/login"...>
。因此,启动rails服务器并转到浏览器并验证页面源,以查看登录的链接标记是否如下所示:<a href="/login"...>
答案 1 :(得分:1)
您正在引用Hartl教程的第8.3节,但看起来您已经开始研究下一部分Remember Me。这是您实现持久会话的地方。
我可以告诉你,因为你的代码中有一些'记住'的东西。例如:
def remember(user)
user.remember
cookies.permanent.signed[:user_id] = user.id
cookies.permanent[:remember_token] = user.remember_token
end
您的测试失败了,因为您可能有一个活跃的记忆令牌Cookie,但您的log_out
方法并没有“忘记”它。从本质上讲,你只完成了一半的Hartl部分;所以测试自然会失败(证明测试工作!)
如果您继续学习本教程,它将指导您在注销时忘记此cookie。或者,您可以回溯并删除8.3之后放置的位。无论哪种方式,这个测试都应该通过。