2016-04-16 5 views
1

Ich beendete Kapitel 11 in Michael Hartls Rails-Tutorial, und danach suchte ich nach einer Möglichkeit, mit der thumbs_up gem einige Reputations- und Voting-Funktionen zu den Mikroposten hinzuzufügen .Aufruf der Namensmethode auf current_user verursacht Testfehler (ruby on rails)

Ich möchte den Ruf des aktuellen Benutzers in einer kleinen Box (wie Stack Overflow) in der Navigationsleiste anzeigen. Ich kann den Benutzernamen und Ruf erhalten fein angezeigt werden:

 <li class="rep_box"><%= current_user.name %> <%= current_user.karma %> </li> 

Die Seite funktioniert gut und macht den Namen des Benutzers und den Ruf richtig, aber jetzt erhalte ich mehrere Fehler und schlägt fehl. Wenn ich die obige Codezeile entferne, funktioniert alles wieder korrekt. Hier

ist ein Beispiel für die Fehler - sie sind alle ziemlich gleich:

>ERROR["test_should_get_home", StaticPagesControllerTest, 2016-04-09 04:36:31 -0400] 
test_should_get_home#StaticPagesControllerTest (1460190991.59s) 
ActionView::Template::Error:   ActionView::Template::Error: undefined method `name' for nil:NilClass 
      app/views/layouts/_header.erb:6:in `_app_views_layouts__header_erb__1475229759153232172_2241208160' 
      app/views/layouts/application.html.erb:12:in `_app_views_layouts_application_html_erb__4357373253304461109_2216429940' 
      test/controllers/static_pages_controller_test.rb:9:in `block in <class:StaticPagesControllerTest>' 
     app/views/layouts/_header.erb:6:in `_app_views_layouts__header_erb__1475229759153232172_2241208160' 
     app/views/layouts/application.html.erb:12:in `_app_views_layouts_application_html_erb__4357373253304461109_2216429940' 
     test/controllers/static_pages_controller_test.rb:9:in `block in <class:StaticPagesControllerTest>' 
+0

Kann jemand überprüfen, ob dies behoben werden kann, indem etwas zur Funktion log_in_as() von test_helper.rb hinzugefügt wird? – gbutters

Antwort

2
undefined method `name' for nil:NilClass 

Das bedeutet, dass current_usernil ist, wenn name auf sie aufgerufen wird. Stellen Sie sicher, dass es an diesem Punkt richtig zugewiesen ist und dass der Fehler verschwindet.

+0

Ich rief .nil? auf current_user.name und es kam falsch zurück. – gbutters

+0

Es sind die Tests, die fehlschlagen. – gbutters

+0

@gButters, versuchen Sie, Ihren Null-Check direkt in die Ansicht zu setzen, damit Sie wissen, dass es im richtigen Kontext ist, z. '<% = puts" cun ?: # {current_user.nil?} "; current_user.name%> ' – Mori

1

Sie müssen sign_in ein Benutzer vor gibt es eine current_user.

let(:curr_user) { User.create(...attrs...) } 
sign_in curr_user 

Vom Devise documentation:

Sie könnte so etwas wie tun

Devise enthält einige Test Helfer für funktionale Spezifikationen. Um verwenden sie, müssen Sie Devise in Ihre Funktionstests von hinzufügen, die folgende an der Unterseite Ihrer test/test_helper.rb Datei hinzufügen (stellen Sie sicher, dass Sie es außerhalb des Geltungsbereichs von ActiveSupport :: TestCase die ist die Standardklasse innerhalb des Test/test_helper.rb):

class ActionController::TestCase 
    include Devise::TestHelpers 
end 

sicher sein, nur dass diese Aufnahme nach dem erfordern gemacht 'rspec/Schienen-Richtlinie.

Jetzt können Sie die Methoden sign_in und sign_out verwenden. Solche Methoden haben die gleiche Signatur wie in Controller:

sign_in :user, @user # sign_in(scope, resource) 
sign_in @user   # sign_in(resource) 

sign_out :user   # sign_out(scope) 
sign_out @user   # sign_out(resource) 

Ansonsten current_user ist, richtig, geht nil zu sein. Wenn Sie möchten, dass Ihr Code dies toleriert, dann sollten Sie dieses Bit in der Ansicht mit etwas wie unless current_user.nil? schützen. Ich habe auch etwas gesehen jemand eine current_user_or_guest Methode erstellen, die ihre Verwendung von current_user ersetzt.

In einem Helfer schufen sie so etwas wie dieses:

def current_or_guest_user 
    if current_user 
     current_user 
    else 
     User.new 
    end 
    end 

EDIT:

In Michael Hartl's Rails tutorial, spielt es keine Devise verwenden und eine current_user Methode, die wie folgt aussieht hat erstellen:

def current_user 
    User.find_by(id: session[:user_id]) 
end 

Wenn es keine session[:user_id] gibt, dieseDie Methodegibt nil zurück. Sie müssen einen Benutzer weiterhin authentifizieren, bevor current_usernil nicht mehr zurückgibt. Es gibt bereits einen Testcode, der die Benutzerauthentifizierung in test/integration/users_login_test.rb testet.

Also, in Ihren Tests müssen Sie sicherstellen, dass etwas wie log_in User.find_by(id: <some valid ID>) ausgeführt wird, um einen Benutzer zu authentifizieren. Dadurch wird sichergestellt, dass current_user wie in einem normalen Verwendungskontext ausgeführt wird.

Sie könnten ein test/support Verzeichnis hinzufügen und innerhalb des von login_helpers.rb mit diesem erstellen:

def log_in_with(email,password) do 
    get login_path 
    post login_path, session: { email: email, password: password } 
end 

Dann, um sicherzustellen, dass diese Methoden zur Verfügung stehen, in Ihrem test/test_helper.rb add:

Dir[Rails.root.join('test/support/**/*.rb')].each { |f| require f } 

Jetzt, In Ihren Tests, die einen authentifizierten Benutzer erfordern, tun Sie Folgendes:

log_in_with('a_valid_email', 'its valid password') 
+0

Es gibt ein bisschen zu testen in der Dokumentation thumbs_up: https://github.com/bouchard/thumbs_up Frage, ob das tun würde? – gbutters

+0

Was benutzt du dann, um die 'current_user' Methode zu erstellen? Das wird nicht von ThumbsUp erstellt. –

+0

Dieses Bit beim Testen dient zum Testen von ThumbsUp und testet nicht die Implementierung von ThumbsUp in Ihrer App. Was Sie tun, ist richtig, Sie verpassen nur etwas, das den aktuellen Benutzer festlegt. –