【问题标题】:RailsTutorial Chapter 8 Tests FailingRailsTutorial 第 8 章测试失败
【发布时间】:2016-07-10 06:53:41
【问题描述】:

我正在阅读 Michael Hartl 的 Rails 教程 (www.railstutorial.org) 的第 8 章,并且遇到了失败的测试(失败和错误)。我花了几个小时试图让这些测试通过,并在 StackOverflow 上阅读了类似的问题,但没有一个答案能解决我的问题。

以下是失败测试的消息:

1) Failure:
UsersSignupTest#test_valid_signup_information [/home/ubuntu/workspace/test/integration/users_signup_test.rb:25]:
expecting <"users/show"> but rendering with <["statics/home", "layouts/_shim", "layouts/_header", "layouts/_footer", "layouts/application"]>

2) Error:
UsersLoginTest#test_login_with_valid_information_followed_by_logout:
NoMethodError: undefined method `[]' for nil:NilClass
app/controllers/sessions_controller.rb:7:in `create'
test/integration/user_login_test.rb:21:in `block in <class:UsersLoginTest>'

3) Error:
UsersLoginTest#test_login_with_invalid_information:
NoMethodError: undefined method `[]' for nil:NilClass
app/controllers/sessions_controller.rb:7:in `create'
test/integration/user_login_test.rb:12:in `block in <class:UsersLoginTest>'

及相关文件:

users_signup_test.rb

require 'test_helper'

class UsersSignupTest < ActionDispatch::IntegrationTest

  test "invalid signup information" do
    get signup_path
    assert_no_difference 'User.count' do
      post users_path, user: { name:  "",
                               email: "user@invalid",
                               password:              "foo",
                               password_confirmation: "bar" }
    end
    assert_template 'users/new'
  end

  test "valid signup information" do
    get signup_path
    assert_difference 'User.count', 1 do
      post users_path, user: { name:  "Example User",
                                        email: "user@stpauls.school.nz",
                                        password:              "password",
                                        password_confirmation: "password" }
    end
    follow_redirect!
    assert_template 'users/show'
    assert is_logged_in?
  end
end

user_login_test.rb

require 'test_helper'

class UsersLoginTest < ActionDispatch::IntegrationTest

  def setup
    @user = users(:someName)
  end

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

  test "login with valid information followed by logout" do
    get login_path
    post login_path, params: { 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
end

sessions_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
      redirect_to root_url
    else
      flash.now[:danger] = 'Invalid email/password combination'
      render 'new'
    end
  end

  def destroy
    log_out
    flash.now[:success] = 'Successfully logged out!'
    redirect_to root_url
  end
end

test_helper.rb

ENV['RAILS_ENV'] ||= 'test'
require File.expand_path('../../config/environment', __FILE__)
require 'rails/test_help'

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...
  def is_logged_in?
    !session[:user_id].nil?
  end

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

sessions_helper.rb

module SessionsHelper

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

  # Returns the current logged-in user (if any).
  def current_user
    @current_user ||= User.find_by(id: session[:user_id])
  end

  # Returns true if the user is logged in, false otherwise.
  def logged_in?
    !current_user.nil?
  end

  # Logs out the current user.
  def log_out
    session.delete(:user_id)
    @current_user = nil
  end

end

users.yml

somename:
  name: "SomeName"
  email: "somename@someemail.com"
  password_digest: <%= User.digest('password') %>

正如我所说,我花了很长时间试图修复这些错误,但没有运气。任何帮助表示赞赏!还值得一提的是,我一直在更改一些变量的名称/值,但我相信我在重命名方面是一致的,所以这应该不会影响任何事情。

很抱歉这篇超长的帖子。

【问题讨论】:

  • params[:session] 最后两个为空...

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


【解决方案1】:

查看错误日志提示以下语法:

Rails 5

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

是 Rails 5 语法。 post 和其他 http 请求方法已在 rails 5 中更改。要解决此问题,升级到 rails 5 只需使用 rails 4 语法:

Rails 4

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

【讨论】:

  • 嗨!感谢您的回答。这修复了错误(看起来你使用了太多}),但测试仍然失败 - 错误消息与我原始问题中的第一条消息相同。
  • 你真的不能尝试使用rails 4更新到rails版本5的railstutorial。我建议从正确的rails版本或正确版本的教程重新开始(旧应该在某处仍然可用)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-03
  • 2014-05-08
  • 1970-01-01
相关资源
最近更新 更多