Wie kann ich Mock-Modelle in AuthLogic Controller-Spezifikationen verwenden?
-
06-07-2019 - |
Frage
Ich versuche, Spezifikationen für einen Controller zu schreiben, ohne Einbauten mit (statt Mock-Modelle einsetzt). Diese Steuerung erfordert einen Benutzer angemeldet sein, für die ich unter Verwendung von AuthLogic nach dem Autors Empfehlungen .
describe UsersController do
def mock_user(stubs={})
@mock_user ||= mock_model(User, stubs)
end
context 'when logged in' do
before { activate_authlogic }
it "exposes the logged-in user as @user in response to GET (show)" do
UserSession.create(mock_user)
...
end
...
end
...
end
All diese Beispiele auf der Linie UserSession.create(...)
versagen, auf die Wirkung der Berichterstattung:
Mock 'User_1005' received unexpected message :changed? with (no args)
Ich bin mir nicht sicher, wie diese zu lösen; mit :changed? => false
angemessen verhöhnt?
Lösung
Iain hat eine Lösung Mock-Objekte mit AuthLogic verwenden. Umformulieren, die folgenden Helfer gehen in spec_helpers.rb
:
def current_user(stubs = {})
@current_user ||= mock_model(User, stubs)
end
def user_session(stubs = {}, user_stubs = {})
@current_user_session ||= mock_model(UserSession, {:user => current_user(user_stubs)}.merge(stubs))
end
def login(session_stubs = {}, user_stubs = {})
UserSession.stub!(:find).and_return(user_session(session_stubs, user_stubs))
end
def logout
@user_session = nil
end
Ich habe dies in meinen Spezifikationen aufgenommen, und ich finde, es tut genau das, was ich hatte gehofft. Ich habe Arbeits Controller Spezifikationen, die Mock-Modelle für den angemeldeten Benutzer exploy, so dass jetzt sie haben nicht alle Pause, wenn ich ein Feld auf Benutzer hinzufügen. Iains Beispiel hierfür in einem spec Implementierung ist als:
describe SecretsController do
before { login }
it "should be very very secret!"
end
P. S. Ich hasse meine eigene Frage zu beantworten, aber das ist die Antwort, die ich suchte; Ich habe einfach nicht finden es früh genug.
Andere Tipps
Authlogic erwartet, dass der Datensatz wirkt wie eine aktive Datensatz Instanz. Sie können eine echte Instanz oder einen Mock verwenden, aber wenn Sie einen Mock / Stub verwenden, müssen Sie sicher sein, es zu allen Methoden, die von Authlogic erforderlich reagiert.
Ich würde vorschlagen, anstelle einem Mock ein echtes aktives Datensatz-Objekt zu verwenden. Wenn Sie nicht über eine Halterung verwenden möchten, können Sie eine Fabrik verwendet werden.
Die letzte Option wäre ein Modell zu übergeben, die auf alle Methoden reagiert (Sie können dies über method_missing leicht erreichen). Das Problem bei dieser Lösung ist, dass Sie nicht im Voraus wissen, welchen Wert einen bestimmten Methodenaufruf zurückgeben sollte.
Ja, können Sie falsch passieren, aber das ist nicht wirklich eine Lösung. Es würde erfordern, manuell versuchen, / fügen Sie einen Standardwert, bis Sie das Mock-Objekt beantworten alle Authlogic Anfrage finden. Aber das müssten Sie ständig folgen authlogic für jede interne Änderung nicht beantworteten Anrufe an Ihre Stummel zu beheben.
In Rails 3 diese Verspottung Usersession funktioniert nicht mehr, da AuthLogic der Usersession keine Instanz von Activerecord :: Base ist. Update, das funktioniert für mich:
class UserSession < Authlogic::Session::Base
extend ActiveModel::Naming
end
fand ich spöttisch authlogic Objekte waren, waren hart und ich gab schließlich auf spöttisch auf. Stattdessen verwende ich jetzt ein Generator Ansatz Papa Objekt. Meine Funktionstests sind jetzt viel glücklicher. BTW, shoulda + object_daddy absolut Felsen. Shoulda des Transaktionskontext sicherstellen, dass meine Testdatenbank bleibt sauber und ich muß in erster Linie einfache Active Objekte nicht verspotten.