2009-11-20 23 views
17

Sto provando a testare il mio controller e mantenere la separazione dei dubbi.RSpec in Rails: Come saltare un before_filter?

La prima preoccupazione è "Chi è in grado di eseguire quale azione?"
Sto usando autlogico per l'autenticazione e be9's acl9 per l'autorizzazione. Ma questo non dovrebbe importare, tutti i miei problemi di autorizzazione sono trattati in un before_filter. Sto verificando un tale before_filter da qualcosa di simile a questo:

describe SomeModelsController, "GET to index (authorization)" do 
    before(:each) do 
    @siteadmin = mock_model(User) 
    @siteadmin.stub!(:has_role?).with("siteadmin", nil).and_return(true) 
    end 

    it "should grant access to a siteadmin" do 
    controller.should_receive(:current_user).at_least(:once).and_return(@siteadmin) 
    get :index 
    response.should be_success 
    end 
end 

Questa spec sta lavorando bene!

Ora, la seconda preoccupazione è "L'azione fa ciò che dovrebbe fare?"
Ciò non implica il controllo dell'autorizzazione. La migliore/soluzione più pulita sarebbe saltando che before_filter tutti insieme e solo fare qualcosa di simile:

describe SomeModelsController, "GET to index (functional)" do 
    it "should find all Models" do 
    Model.should_receive(:find).with(:all) 
    end 
end 

Senza doversi preoccupare di quale utente con il ruolo che vanta effettuale il login per prima. In questo momento ho risolto così:

describe SomeModelsController, "GET to index (functional)" do 
    before(:each) do 
    @siteadmin = mock_model(User) 
    @siteadmin.stub!(:has_role?).with("siteadmin", nil).and_return(true) 
    controller.stub!(:current_user).and_return(@siteadmin) 
    end 

    it "should find all Models" do 
    Model.should_receive(:find).with(:all) 
    end 
end 

Se ora ho deciso che il mio siteadmin non ha il diritto di accedere più l'azione index, sarebbe non solo rompere uno spec - cioè le specifiche che deve rompere in un caso del genere - ma anche la seconda specifica totalmente indipendente.

So che questo è fondamentalmente un problema minore, ma sarebbe bello se qualcuno potesse trovare una soluzione (elegante)!

risposta

34

Per saltare il filtro prima:

controller.class.skip_before_filter :name_of_method_used_as_before_filter 

L'unico accorgimento (mentioned the docs) è che questo funziona solo per i filtri metodo-riferimento, non procs.

In alternativa, si potrebbe stub current_user.has_role?

describe SomeModelsController, "GET to index (functional)" do 
    before(:each) do 
    controller.current_user.stub!(:has_role?).and_return(true) 
    end 

    it "should find all Models" do 
    Model.should_receive(:find).with(:all) 
    end 
end 
+0

Grazie, non ho pensato a questo. Se non c'è modo di saltare il before_filter, questa potrebbe essere la soluzione migliore. – sebastiangeiger

+0

Ok, ho aggiornato la mia risposta. Speriamo che sia quello di cui avevi bisogno. – Baldu

+0

Bello, saltando il filtro precedente funziona. L'unico lato negativo è che acl9 installa un filtro lambda senza nome per impostazione predefinita, quindi devo forzare la creazione di un named before_filter. – sebastiangeiger

-9

ne dite semplicemente non fare una richiesta GET? Prova a chiamare il metodo controller da solo.

controller.index 
0

Vecchia domanda, ma ho dovuto risolvere questo solo di recente. Questo funziona solo per Rails 3.1, per le versioni precedenti è necessario sostituire _process_action_callbacks con filter_chain (non testato)

Si può semplicemente eliminare un Proc corrispondente dalla catena dei filtri in questo modo (ad esempio Test :: Unit):

class RandomControllerTest < ActionController::TestCase 
    def setup 
    @controller.class._process_action_callbacks.each do |f| 
     @controller.class._process_action_callbacks.delete(f) if f.raw_filter.to_s.match(/**<match for your proc>**/) 
    end 
    end 
end 
Problemi correlati