rails before application after_action ruby-on-rails rspec separation-of-concerns before-filter

ruby-on-rails - before - routes in ruby on rails



RSpec en Rails: ¿Cómo omitir un before_filter? (3)

¿Qué hay de no hacer una solicitud GET? Intenta llamar al método del controlador por sí mismo.

controller.index

Estoy tratando de probar mi controlador y mantengo la separación de inquietudes.

La primera preocupación es "¿Quién es capaz de ejecutar qué acción?"
Estoy usando authlogic para la autenticación y be9''s acl9 para la autorización. Pero esto no debería importar, todas mis preocupaciones de autorización se manejan en un before_filter . Estoy probando tal before_filter por algo similar a esto:

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

Esta especificación está funcionando bien!

Ahora, la segunda preocupación es "¿La acción hace lo que se supone que debe hacer?"
Esto no implica la verificación de la autorización. La solución mejor / más limpia sería saltear ese antes de before_filter todos juntos y simplemente hacer algo como:

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

Sin tener que preocuparse por qué usuario con qué rol debe iniciar sesión primero. Ahora mismo lo resolví así:

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

Si ahora decidiera que mi siteadmin ya no tiene derecho a acceder a la acción de índice, no solo rompería una especificación, es decir, la especificación que TIENE que romper en ese caso, sino también la segunda especificación totalmente no relacionada.

Sé que esto es básicamente un problema menor, pero sería bueno si alguien pudiera encontrar una solución (elegante).


Para omitir el filtro anterior:

controller.class.skip_before_filter :name_of_method_used_as_before_filter

La única advertencia ( mencionada en los documentos ) es que esto solo funcionará para los filtros de referencia de método, no para los procesos.

Alternativamente, usted podría apalear 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


Vieja pregunta, pero tuve que resolver esto recientemente. Esto solo funcionará para Rails 3.1, para versiones anteriores debe reemplazar _process_action_callbacks con filter_chain (no probado)

Simplemente puede eliminar un Proc coincidente de la cadena de filtros, de este modo (Ejemplo de 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