Rails测试无法断言链接的存在,即使它实际上在浏览器上有效

时间:2017-05-11 08:26:58

标签: ruby-on-rails

我正在关注Hartl的rails教程(第10章),并且正在编写一个测试来验证所有布局链接是否存在。这是测试文件: -

require 'test_helper'

class SiteLayoutTest < ActionDispatch::IntegrationTest

  def setup
    @user = users(:michael)
  end

  test "layout links" do
    get root_path
    assert_template 'static_pages/home'
    assert_select "a[href=?]", root_path, count: 2
    assert_select "a[href=?]", blog_path
    assert_select "a[href=?]", about_path
    assert_select "a[href=?]", help_path
    assert_select "a[href=?]", contact_path
    assert_select "a[href=?]", login_path
    assert_select "a[href=?]", logout_path, count: 0
    assert_select "a[href=?]", users_path, count: 0
    log_in_as(@user)
    assert is_logged_in?
    assert_select "a[href=?]", users_path
    assert_select "a[href=?]", logout_path
    assert_select "a[href=?]", login_path, count: 0
  end
end

此处,测试显示以下故障: -

    FAIL["test_layout_links", SiteLayoutTest, 0.7809554979976383]
 test_layout_links#SiteLayoutTest (0.78s)
        Expected at least 1 element matching "a[href="/users"]", found 0..
        Expected 0 to be >= 1.
        test/integration/site_layout_test.rb:23:in `block in <class:SiteLayoutTest>'

如果我注释掉assert_select "a[href=?]", users_path,则会显示logout_path失败: -

 FAIL["test_layout_links", SiteLayoutTest, 0.6692811190005159]
 test_layout_links#SiteLayoutTest (0.67s)
        Expected at least 1 element matching "a[href="/logout"]", found 0..
        Expected 0 to be >= 1.
        test/integration/site_layout_test.rb:24:in `block in <class:SiteLayoutTest>'

这是包含users_path和logout_path链接的标题部分: -

<header class="navbar navbar-fixed-top navbar-inverse">
  <div class="container">
    <%= link_to "Sample app", root_path, id: "logo" %>
    <nav>
      <ul class="nav navbar-nav navbar-right">
        <li><%= link_to "Home",   root_path %></li>
        <% if logged_in? %>
          <li><%= link_to "Users", users_path %></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", edit_user_path(current_user) %></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 %>
        <li><%= link_to "Blog",   blog_path %></li>
      </ul>
    </nav>
  </div>
</header>

但正如您在此screenshot中所看到的,用户和注销按钮确实存在,并且它们按预期工作。

我试图弄清楚为什么测试失败,即使应用程序中的实际功能有效。帮助将不胜感激。

更新: -

is_logged_in?log_in_as method的定义: -

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

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

  # Log in as a particular user.
  def log_in_as(user)
    session[:user_id] = user.id
  end
end

class ActionDispatch::IntegrationTest

  # Log in as a particular user.
  def log_in_as(user, password: 'password', remember_me: '1')
    post login_path, params: { session: { email: user.email,
                                          password: password,
                                          remember_me: remember_me }}
  end
end

logged_in?的定义: -

module SessionsHelper

  # Logs in the given user.
  def log_in(user)
    session[:user_id] = user.id
  end

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

  def current_user?(user)
    user == current_user
  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

  def logged_in?
    !current_user.nil?
  end

1 个答案:

答案 0 :(得分:0)

$\phi$使用会话变量为您设置,但它不刷新视图,因此您仍然拥有原始显示。

你应该做

log_in_as