Image for post
Image for post
Revolution Rail Co. photo

Probando acciones de controladores sin ejecutar los filtros en Ruby on Rails

Muchas de las acciones de los controladores de una aplicacación Ruby on Rails tienen relacionado un método que se debe ejecutar antes que la propia acción, estós métodos están definidos por before_action.

Cuando probamos estas acciones en los controladores, lo que se quiere es probar la acción en si y no el método del before_action.

Como ejemplo de este artículo, la premisa es que la aplicación está construida en Ruby on Rails y se usa RSpec para las pruebas.

Uno de los métodos más usados en los filtros de controladores es el de verificar que el usuario esté autentificado, o en el caso de un API, que tenga el token de acceso.

module Api
module V1
class ApiController < ActionController::Base
respond_to :json
before_action :restrict_access_by_token def ping
head :ok
end
private def restrict_access_by_token
authenticate_or_request_with_http_token do |token|
@company = Company.find_by(api_token: token)
end
end
end
end
end

Para la action ping se tiene lo siguiente en nuestro archivo de routes routes.rb

  namespace :api, defaults: {format: :json} do
scope module: :v1 do
match "ping", to: "api#ping", via: :get
end
end

Se quiere probar que la action ping tenga una respuesta favorable, para esto se ha escrito la siguiente prueba en el archivo spec/controllers/api_controller_spec.rb

require 'rails_helper'
RSpec.describe Api::V1::ApiController, type: :controller do
describe 'Api Controller Tests ' do
it ' success ping action ' do
get :ping
expect(response).to have_http_status(:success)
end
end
end

Al ejecutar las pruebas se tiene el siguiente resultado:

FFailures:1) Api::V1::ApiController Api Controller Tests   succes ping action 
Failure/Error: expect(response).to have_http_status(:success)
expected the response to have a success status code (2xx) but it was 401
# ./spec/controllers/api_controller_spec.rb:6:in `block (3 levels) in <top (required)>'
Finished in 5.25 seconds (files took 3.69 seconds to load)
1 example, 1 failure
Failed examples:rspec ./spec/controllers/api_controller_spec.rb:4 # Api::V1::ApiController Api Controller Tests succes ping action

Esta falla se produce porque al ejecutar la acción restrict_access_by_token se produce un error que lanza una excepción.

Pero como, en este caso, no interesa probar el método restrict_access_by_token que debería ser probado individualmente, se plantean 2 trucos para que la prueba salte este filtro.

El primero es hacer una simulación de la respuesta del método restrict_access_by_token usando un RSpec Mock para simular la respuesta del método llamado por el filtro. Para este caso, se usó:

allow(controller).to receive(:restrict_access_by_token).and_return(true)

Entonces, el código de la prueba queda:

require 'rails_helper'
RSpec.describe Api::V1::ApiController, type: :controller do
describe 'Api Controller Tests ' do
it ' succes ping action ' do
allow(controller)
.to receive(:restrict_access_by_token)
.and_return(true)

get :ping
expect(response).to have_http_status(:success)
end
end
end

La otra opción propuesta es usar skip_before_action directamente en el código de la prueba. Así se tiene

require 'rails_helper'
RSpec.describe Api::V1::ApiController, type: :controller do
describe 'Api Controller Tests ' do
it ' succes ping action ' do
controller.class.skip_before_action :restrict_access_by_token
get :ping
expect(response).to have_http_status(:success)
end
end
end

También se tendría la opción de probar en conjunto todo. En este caso se deberá proveer en la prueba una cabecera de conexión que contenga un token válido.

Recomendación

Para el caso del ejemplo, es recomendable usar el método del skip_before_action ya que queda explícito en la prueba, que se está evitando realizar el filtro mencionado.

Para caso de validaciones, como permisos, verificaciones de banderas, etc, es preferible usar RSpec Mock para obtener el resultado deseado para cada caso.

Si te gustó este artículo, por favor aplaude las veces que quieras, y para ver historias similares acerca de tecnología, mira nuestras publicaciones y escribe en los comentarios cualquier duda que tengas o si quieres que escribamos de algo en particular.

Milber

Mail: milber@alturasoluciones.com
LinkedIn: https://www.linkedin.com/in/milberchamputiz/

AlturaSoluciones

IT consulting.

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store