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?

War es hilfreich?

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.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top