Rails 4 - undefined method 'authenticate'

2019-07-16 12:23发布

问题:

I'm working on a course building a social network using Rails 4 & Devise.

I'm stuck trying to get a course to pass, this is the error I'm getting:

1) Error:
UserFriendshipsControllerTest#test_: #new when not logged in should get redirected to the login page. :
NoMethodError: undefined method `authenticate!' for nil:NilClass
    test/controllers/user_friendships_controller_test.rb:8:in `block (3 levels) in <class:UserFriendshipsControllerTest>'

This is my users_friendships_controller_test.rb :

require 'test_helper'

class UserFriendshipsControllerTest < ActionController::TestCase

context "#new" do
    context "when not logged in" do
        should "get redirected to the login page" do
            get :new
            assert_response :redirect
      end
    end
  end
end

My user_friendship.rb:

class UserFriendship < ActiveRecord::Base
    belongs_to :user
    belongs_to :friend, class_name: "User", foreign_key: "friend_id"

    private

        def friendship_params
            params.require(:user).permit(:user_id, :friend_id, :friend)
        end
end

The only thing I've added to my user_friendships_controller.rb is a blank new method and:

before_filter :authenticate_user!, only: [:new]

Please let me know if I should post any more code.

Thank you

回答1:

I've found answer in documentation:

If you choose to authenticate in routes.rb, you lose the ability to test your routes via assert_routing (which combines assert_recognizes and assert_generates, so you lose them also). It's a limitation in Rails: Rack runs first and checks your routing information but since functional/controller tests run at the controller level, you cannot provide authentication information to Rack which means request.env['warden'] is nil and Devise generates one of the following errors:

NoMethodError: undefined method 'authenticate!' for nil:NilClass
NoMethodError: undefined method 'authenticate?' for nil:NilClass

The solution is to test authenticated routes in the controller tests. To do this, stub out your authentication methods for the controller test.

How to stub authentication.