rails rack_test feature example ruby-on-rails ruby rspec capybara

ruby-on-rails - rack_test - ruby on rails selenium



Cómo apilar el método ApplicationController en la especificación de solicitud (6)

Necesito resguardar la respuesta de un método current_user en una especificación de solicitud Rspec / capybara. El método se define en ApplicationController y está utilizando helper_method. El método simplemente debe devolver una identificación de usuario. Dentro de la prueba, me gustaría que este método devuelva el mismo ID de usuario cada vez.

Alternativamente, podría solucionar mi problema configurando la session[:user_id] en la especificación (que es lo que current_user devuelve) ... pero eso tampoco parece funcionar.

¿Alguno de estos es posible?

Editar:

Esto es lo que tengo (no funciona. Simplemente ejecuta el método normal de usuario actual).

require ''spec_helper'' describe "Login" do before(:each) do ApplicationController.stub(:current_user).and_return(User.first) end it "logs in" do visit ''/'' page.should have_content("Hey there user!") end end

También no funciona:

require ''spec_helper'' describe "Login" do before(:each) do @mock_controller = mock("ApplicationController") @mock_controller.stub(:current_user).and_return(User.first) end it "logs in" do visit ''/'' page.should have_content("Hey there user!") end end


Aquí hay un par de ejemplos de la forma básica.

controller.stub(:action_name).and_raise([some error]) controller.stub(:action_name).and_return([some value])

En su caso particular, creo que la forma correcta sería:

controller.stub(:current_user).and_return([your user object/id])

Aquí hay un ejemplo completo de trabajo de un proyecto en el que trabajo:

describe PortalsController do it "if an ActionController::InvalidAuthenticityToken is raised the user should be redirected to login" do controller.stub(:index).and_raise(ActionController::InvalidAuthenticityToken) get :index flash[:notice].should eql("Your session has expired.") response.should redirect_to(portals_path) end end

Para explicar mi ejemplo completo, básicamente, lo que hace es verificar que, cuando se ActionController::InvalidAuthenticityToken error ActionController::InvalidAuthenticityToken en cualquier lugar de la aplicación, aparece un mensaje flash y el usuario se redirige a la acción portals_controller#index . Puede usar estos formularios para anular y devolver valores específicos, probar una instancia de un error dado que se está .stub(:action_name).and_[do_something_interesting]() , etc. Hay varios .stub(:action_name).and_[do_something_interesting]() disponibles para usted.

Actualización (después de haber agregado su código): según mi comentario, cambie su código para que diga:

require ''spec_helper'' describe "Login" do before(:each) do @mock_controller = mock("ApplicationController") @mock_controller.stub(:current_user).and_return(User.first) end it "logs in" do visit ''/'' page.should have_content("Hey there user!") end end


Esto funciona para mí y me da una variable @current_user para usar en las pruebas.

Tengo un ayudante que se ve así:

def bypass_authentication current_user = FactoryGirl.create(:user) ApplicationController.send(:alias_method, :old_current_user, :current_user) ApplicationController.send(:define_method, :current_user) do current_user end @current_user = current_user end def restore_authentication ApplicationController.send(:alias_method, :current_user, :old_current_user) end

Y luego en mis especificaciones de solicitud, llamo:

before(:each){bypass_authentication} after(:each){restore_authentication}


Ninguna de las respuestas proporcionadas funcionó para mí. Como en la publicación original de @ matt-fordam, tengo una especificación de solicitud, no una especificación de controlador. La prueba solo muestra la vista sin iniciar un controlador.

Resolví esto anulando el método en la vista como se describe en esta otra publicación SO

view.stub(:current_user).and_return(etc)


Para Rspec 3+ la nueva API es:

Para una prueba de controlador, agradable y corto:

allow(controller).to receive(:current_user).and_return(@user)

O para todas las instancias de ApplicationController:

allow_any_instance_of(ApplicationController).to receive(:current_user).and_return(@user)


Para cualquier otra persona que necesite un método de control de aplicación que establezca un ivar (y se quedó bloqueado por la interminable masturbación sobre por qué no debería hacer eso), esta es una forma que funciona, con el sabor de Rspec de octubre de 2013.

before(:each) do campaign = Campaign.create! ApplicationController.any_instance.stub(:load_campaign_singleton) controller.instance_eval{@campaign = campaign} @campaign = campaign end

corta el método para no hacer nada, y establece el ivar en la instancia del controlador rspec, y lo pone a disposición de la prueba como @campaign.


skalee parece haber proporcionado la respuesta correcta en el comentario.

Si el método que intentas eliminar es un método de instancia (lo más probable) y no un método de clase, entonces necesitas usarlo:

ApplicationController.any_instance.stub(:current_user)