Dos casos que ayudarán a mejorar tu cobertura de tests con RSpec

Por

1. Declarar headers para controlar las condiciones del request

Hace poco tuve que testear una acción de controlador que realiza unas transacciones, y luego hace un redirect a la misma url de origen (el referer). En un principio no pensé que fuera algo complicado, pero en el primer intento un error me advirtió que tenía que encontrar la forma de especificar en el test la url desde donde se generaba el request.


ActionController::ActionControllerError:
 Cannot redirect to nil!

Solucionar esto no es algo que se encuentre fácil en la documentación o buscando en Google, pero nada de eso importa cuando tu CTO llega con la solución en menos de 5 minutos. Existe una hermosa forma de pasarle headers a los specs de controlador y, con eso, declarar el referer es pan comido. Aquí un ejemplo de lo simple que es:

it 'Redirect to referer' do
  request.headers['HTTP_REFERER'] = '/my-path'
  post :my_action, params: {id: 1}
  expect(subject).to redirect_to('/my-path')
end

Hasta este caso nunca había pensado en la importancia de declarar headers en un test, pero ¿qué pasa si necesitas algo más complejo? ¿Qué pasa si necesitas probar en un API condiciones de CORS? De seguro en ese caso te será muy útil poder declarar los headers de la petición.


2. Verificar que la respuesta de un JSON incluya el contenido que esperas

Teniendo que verificar que un endpoint retornara distintos valores dependiendo los roles del usuario, tuve que entrar en el mundo de testear las respuestas de un JSON. No soy un desarrollador back-end experimentado y esperaba que esto fuese algo complejo, dominio de quienes estuviesen acostumbrados a crear APIs, pero luego de unos minutos pude ver lo sencillo que es. Para quienes estamos aprendiendo, es tan simple como recurrir al viejo y conocidoJSON.parse(response.body).


Si la respuesta que esperas tiene el siguiente formato:

jobs: [
  {
    id: 1,
    title: 'Awesome DevOps',
    important_attribute: 'my_value',
  }
]

Y si además necesitas chequear que el valor de important_attribute sea 'my_value', tu test debiese ser más o menos así:


it 'Includes my_value' do
  get :my_endpoint, params: { id: 1 }
  expect(response).to have_http_status(:success)
  json_response = JSON.parse(response.body)
  expect(json_response['important_attribute']).to eq('my_value')
end

Fácil, ¿no?


Conclusión

Para quienes tenemos menos experiencia haciendo back-end, a veces incluir test para ciertos escenarios puede parecer intimidante, pero la verdad es que sólo hay que tener paciencia y no rendirse en tratar de cubrir la mayor cantidad de situaciones posibles. Esto siempre será una inversión para la salud del equipo y la confiabilidad de tu proyecto de cara a los usuarios, en especial si tu equipo es pequeño y el tiempo no sobra.


Lo más reciente en Blog