Wie legen Sie beim Schreiben einer Anforderungsspezifikation Sitzungen und / oder Stub-Controller-Methoden fest? Ich versuche, die Authentifizierung in meinen Integrationstests zu unterbinden - rspec / request
Hier ist ein Beispiel für einen Test
require File.dirname(__FILE__) + '/../spec_helper'
require File.dirname(__FILE__) + '/authentication_helpers'
describe "Messages" do
include AuthenticationHelpers
describe "GET admin/messages" do
before(:each) do
@current_user = Factory :super_admin
login(@current_user)
end
it "displays received messages" do
sender = Factory :jonas
direct_message = Message.new(:sender_id => sender.id, :subject => "Message system.", :content => "content", :receiver_ids => [@current_user.id])
direct_message.save
get admin_messages_path
response.body.should include(direct_message.subject)
end
end
end
Der Helfer:
module AuthenticationHelpers
def login(user)
session[:user_id] = user.id # session is nil
#controller.stub!(:current_user).and_return(user) # controller is nil
end
end
Und der ApplicationController, der die Authentifizierung übernimmt:
class ApplicationController < ActionController::Base
protect_from_forgery
helper_method :current_user
helper_method :logged_in?
protected
def current_user
@current_user ||= User.find(session[:user_id]) if session[:user_id]
end
def logged_in?
!current_user.nil?
end
end
Warum ist es nicht möglich, auf diese Ressourcen zuzugreifen?
1) Messages GET admin/messages displays received messages
Failure/Error: login(@current_user)
NoMethodError:
undefined method `session' for nil:NilClass
# ./spec/requests/authentication_helpers.rb:3:in `login'
# ./spec/requests/message_spec.rb:15:in `block (3 levels) in <top (required)>'
quelle
ActionDispatch::IntegrationTest
wurde entwickelt, um einen oder mehrere Benutzer zu simulieren, die über Browser interagieren, ohne echte Browser verwenden zu müssen. In einem Beispiel gibt es möglicherweise mehr als einen Benutzer (dh eine Sitzung) und mehr als einen Controller, und die Sitzungs- / Controller-Objekte sind diejenigen, die in der letzten Anforderung verwendet wurden. Sie haben vor einer Anfrage keinen Zugriff darauf.page.driver.post
mit Capybarapage.driver.post
kann ein Antimuster sein, laut Jonas Nicklas in Capybara und Test-APIs )Hinweis für Gerätebenutzer ...
Übrigens, die Antwort von @David Chelimsky muss möglicherweise etwas angepasst werden, wenn Sie Devise verwenden . Was ich in meinen Integrations- / Anforderungstests mache (dank dieses StackOverflow-Beitrags ):
quelle
devise_for :users
in derconfig/routes.rb
Datei haben. Wenn Sie etwas anderes angegeben haben, müssen Sie Ihren Code entsprechend anpassen.'user[email]' => user.email
,'user[username]' => user.username
da meine App den Benutzernamen als Login anstelle von E-Mail verwendet.FWIW, als ich meine Test :: Unit-Tests auf RSpec portierte, wollte ich mich in meinen Anforderungsspezifikationen mit mehreren (Entwurfs-) Sitzungen anmelden können. Es hat ein bisschen gegraben, aber das hat für mich funktioniert. Verwenden von Rails 3.2.13 und RSpec 2.13.0.
Und...
Bearbeiten : Tippfehler behoben
quelle
Sie könnten die Sitzung auch ziemlich leicht abbrechen.
Alle Ruby-Spezialoperatoren sind in der Tat Methoden. Das Aufrufen
1+1
ist dasselbe wie1.+(1)
, was bedeutet, dass+
es nur eine Methode ist. Ebensosession[:user_id]
ist das gleiche wie das Aufrufen von method[]
onsession
, assession.[](:user_id)
quelle
Ich fand das sehr hilfreich für Devise: https://github.com/plataformatec/devise/wiki/How-To:-Test-controllers-with-Rails-3-and-4-(and-RSpec)
quelle