【问题标题】:Tests failing with undefined method `authenticate!' for nil:NilClass使用未定义的方法“验证!”测试失败对于零:NilClass
【发布时间】:2017-07-05 05:27:37
【问题描述】:

我搜索了该错误并获得了 Rspec 的各种解决方案。
我正在使用 Minitest,但无法理解如何在 Minitest 中实现它。

据我了解,我应该通过调用include Devise::TestHelpers在“test_helper.rb”中登录用户

我正在使用
红宝石 2.1.1p76
Rails 4.2.5.1
耙 11.1.2
迷你测试

我收到以下错误:

LocationsControllerTest#test_should_get_index:
ActionView::Template::Error: undefined method `authenticate' for nil:NilClass
    app/views/layouts/_navbar.html.erb:41:in `_app_views_layouts__navbar_html_erb__1573266900144599421_47382981019560'
    app/views/layouts/application.html.erb:19:in `_app_views_layouts_application_html_erb___1642478743058061304_47382980397060'
    test/controllers/locations_controller_test.rb:9:in `block in <class:LocationsControllerTest>'

_navbar.html.erb:41

<% if current_user %>

test_helpers.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...
end

测试/控制器/locations_controller_test.rb

require 'test_helper'

class LocationsControllerTest < ActionController::TestCase
  setup do
    @location = locations(:one)
  end

  test "should get index" do
    get :index
    assert_response :success
    assert_not_nil assigns(:locations)
  end

  test "should get new" do
    get :new
    assert_response :success
  end

  test "should create location" do
    assert_difference('Location.count') do
      post :create, location: { long_name: @location.long_name, short_name: @location.short_name }
    end

    assert_redirected_to location_path(assigns(:location))
  end

  test "should show location" do
    get :show, id: @location
    assert_response :success
  end

  test "should get edit" do
    get :edit, id: @location
    assert_response :success
  end

  test "should update location" do
    patch :update, id: @location, location: { long_name: @location.long_name, short_name: @location.short_name }
    assert_redirected_to location_path(assigns(:location))
  end

  test "should destroy location" do
    assert_difference('Location.count', -1) do
      delete :destroy, id: @location
    end

    assert_redirected_to locations_path
  end
end

test/fixtures/users.yml

one:
  email: user_email@som.com
  encrypted_password: abc
  sign_in_count: 2
  current_sign_in_at: Time.now

【问题讨论】:

    标签: ruby-on-rails ruby rspec devise minitest


    【解决方案1】:

    您首先需要在 test_helper.rb 中添加对 Devise minitest 助手的调用

    class ActionController::TestCase
      include Devise::Test::ControllerHelpers
    end
    

    或者,如果您有较旧版本的 Devise:

    class ActionController::TestCase
      include Devise::TestHelpers
    end
    

    然后,您需要在用户应登录的每个测试之前添加对 sign_in 的调用。在您的示例中,将设置更改为:

    setup do
      sign_in users(:one)
      @location = locations(:one)
    end
    

    正如@Iceman 指出的,这是documented in the Devise README

    【讨论】:

    • 最新的方法是包含include Devise::Test::ControllerHelpers
    • @ReggieB 我可以登录用户,但不能登录管理员用户。因此,我需要管理员登录的页面将我重定向到断言 302 而不是成功的登录页面。
    • @KartikeyTanna 你如何定义管理员用户?是否有 Admin 或 AdminUser 模型,或者某些用户是管理员?
    • 我是通过 AdminUser 模块来做的。
    • 在我看来 admin_user 已登录以进行测试。问题不在于测试 - 如果您希望管理员用户访问这些页面,您将需要更新您的控制器代码。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多