Rails, Erholsamer Authentication & RSpec - Wie neue Modelle zu testen, die eine Authentifizierung erfordern
-
09-06-2019 - |
Frage
Ich habe eine Lernanwendung erstellt mit Bort , die eine Basis-Anwendung, die Authentifizierung und Restful RSpec enthält. Ich habe es zum Laufen und habe ein neues Objekt, bei den Benutzern angemeldet sein, bevor sie irgendetwas tun können (before_filter :login_required
in der Steuerung). [Edit:. Ich sollte auch erwähnen, dass der Benutzer has_many
der neuen Klasse und nur der Benutzer in der Lage sein sollte, es sehen]
Ich habe das neue Modell / Controller Rspec der Generatoren erzeugt, die eine Reihe von Standardtests erstellt haben. Sie alle passieren, wenn es keine before_filter
ist aber mehrere fehlschlagen, wie zu erwarten, sobald das before_filter
an seinem Platz ist.
Wie erhalte ich die generierten Tests zu laufen, als ob es ist / ist nicht ein angemeldeter Benutzer? Muss ich eine ganze Charge von nicht angemeldet Matching - Tests umleiten? Ich nehme an, es irgendeine Art von spöttischer oder Befestigungstechnik ist, aber ich bin neu in RSpec und ein wenig hilflos. Gut RSpec Tutorial Links würde auch geschätzt werden.
Lösung
Ich habe ein sehr ähnliches Setup, und unten ist der Code ich zur Zeit mit diesen Sachen zu testen. In jedem des describe
s habe ich in:
it_should_behave_like "login-required object"
def attempt_access; do_post; end
Wenn alles, was Sie brauchen, ist ein Login, oder
it_should_behave_like "ownership-required object"
def login_as_object_owner; login_as @product.user; end
def attempt_access; do_put; end
def successful_ownership_access
response.should redirect_to(product_url(@product))
end
Wenn Sie Eigentum. Offensichtlich ändern sich die Hilfsmethoden (sehr wenig) mit jeder Umdrehung, aber das macht die meiste Arbeit für Sie. Dies ist in meinem spec_helper.rb
shared_examples_for "login-required object" do
it "should not be able to access this without logging in" do
attempt_access
response.should_not be_success
respond_to do |format|
format.html { redirect_to(login_url) }
format.xml { response.status_code.should == 401 }
end
end
end
shared_examples_for "ownership-required object" do
it_should_behave_like "login-required object"
it "should not be able to access this without owning it" do
attempt_access
response.should_not be_success
respond_to do |format|
format.html { response.should be_redirect }
format.xml { response.status_code.should == 401 }
end
end
it "should be able to access this if you own it" do
login_as_object_owner
attempt_access
if respond_to?(:successful_ownership_access)
successful_ownership_access
else
response.should be_success
end
end
end
Andere Tipps
Wenn nicht die Authentifizierungs Testen aber die Steuerungen, die die Benutzer testen I die Filtermethode in der Regel authentifiziert werden muss Stummel:
before(:each) do
controller.stub!(:authenticate).and_return(true)
end
Das obige Beispiel funktioniert, wo meine before_filter der authenticate Methode festgelegt ist:
before_filter :authenticate
und die authenticate in meiner App nutzt HTTP-Basic-Authentifizierung, aber es kann wirklich jeder andere Authentifizierungs-Mechanismus sein.
private
def authenticate
authenticate_or_request_with_http_basic do |user,password|
user == USER_NAME && password == PASSWORD
end
end
Ich denke, es ist eine ziemlich einfache Art und Weise zu testen.
fand ich ein paar Antworten auf meine eigene Frage. Im Grunde genommen, musste ich verstehen, wie die Benutzer von restful_authentication
zu verspotten, so dass die automatisch generierte rspec Controller Tests bestehen könnten, obwohl ich hinzugefügt before_filter: login_required
hatte.
Hier sind ein paar meiner gerade gefundenen Ressourcen:
RSpec: Es sollte benehmen sich wie
rspec, restful_authentication und login_required
mit restful_authentication current_user innerhalb Controller Spezifikationen
Um einen Benutzer zu verspotten angemeldet ist, hacke ich in die Steuerung @current_user
auch manuell einstellen:
module AuthHelper
protected
def login_as(model, id_or_attributes = {})
attributes = id_or_attributes.is_a?(Fixnum) ? {:id => id} : id_or_attributes
@current_user = stub_model(model, attributes)
target = controller rescue template
target.instance_variable_set '@current_user', @current_user
if block_given?
yield
target.instance_variable_set '@current_user', nil
end
return @current_user
end
def login_as_user(id_or_attributes = {}, &block)
login_as(User, id_or_attributes, &block)
end
end