Domanda

Sto provando a scrivere le specifiche per un controller senza usare dispositivi (invece usando modelli simulati). Questo controller richiede l'accesso di un utente, per il quale sto impiegando AuthLogic , seguendo la consigli dell'autore .

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

Questi esempi falliscono tutti nella riga UserSession.create (...) , riferendosi all'effetto di:

Mock 'User_1005' received unexpected message :changed? with (no args)

Non sono sicuro di come risolverlo; è beffardo con : cambiato? = & Gt; false appropriato?

È stato utile?

Soluzione

Iain ha pubblicato una all'utilizzo di oggetti finti con AuthLogic . Per riformulare, i seguenti helper vanno 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

L'ho incorporato nelle mie specifiche e trovo che faccia esattamente quello che speravo. Ho specifiche del controller funzionanti che implementano modelli simulati per l'utente che ha effettuato l'accesso, quindi ora non si interrompono tutti quando aggiungo un campo all'utente. L'esempio di Iain di implementarlo in una specifica è:

describe SecretsController do
  before { login }
  it "should be very very secret!"
end

P.S. Odio rispondere alla mia domanda, ma questa è la risposta che cercavo; Non l'ho trovato abbastanza presto.

Altri suggerimenti

Authlogic prevede che il record si comporti come un'istanza di record attiva. Puoi usare un'istanza reale o un mock, ma se usi un mock / stub devi assicurarti che risponda a tutti i metodi richiesti da Authlogic.

Suggerirei di usare un vero oggetto record attivo invece di un mock. Se non vuoi usare un apparecchio, puoi usare una Fabbrica.

L'ultima opzione sarebbe quella di passare un mock che risponde a qualsiasi metodo (puoi facilmente farlo tramite method_missing). Il problema con questa soluzione è che non sai in anticipo quale valore dovrebbe restituire una specifica chiamata di metodo.

Sì, puoi passare false, ma questa non è davvero una soluzione. Richiederebbe di provare manualmente / aggiungere un valore predefinito fino a quando l'oggetto simulato non risponde a tutte le richieste Authlogic. Ma ciò richiederebbe che seguissi costantemente authlogic per qualsiasi modifica interna per correggere chiamate senza risposta al tuo stub.

In Rails 3 questa derisione di UserSession non funziona più, poiché UserSession di AuthLogic non è un'istanza di ActiveRecord :: Base. Correzione che funziona per me:

class UserSession < Authlogic::Session::Base
  extend ActiveModel::Naming
end

Ho scoperto che gli oggetti beffardi dell'autenticazione erano difficili e alla fine ho rinunciato a deridere. Invece, ora uso un approccio di generatori usando object daddy . I miei test funzionali sono molto più felici ora. A proposito, shoulda + object_daddy è assolutamente incredibile. I contesti transazionali di Shoulda assicurano che il mio database di test rimanga pulito e non devo in primo luogo prendere in giro semplici oggetti activerecord.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top