Pruebas TDD para crear y actualizar posts

Clase 13 de 33Curso de Creación de APIs con Ruby on Rails

Resumen

Aprende a cubrir la creación y actualización de posts con enfoque TDD, asegurando rutas, validaciones y estados HTTP correctos. Desde los datos mínimos del payload hasta las respuestas esperadas, aquí se explica paso a paso cómo estructurar las pruebas de post y put para garantizar calidad y claridad desde el inicio.

¿Qué se construye con TDD en la creación y actualización de posts?

Empezamos por las pruebas: una para el método post (crear) y otra para put (actualizar). Se prepara un payload con título, contenido, estado de publicación y user ID. Se aclara que “post” se refiere al método HTTP, no al modelo. Tras enviar la petición al endpoint "posts", se parsea la respuesta con json.parse sobre response.body y se validan estructura, ID y estado HTTP esperado.

Además, se explica que en describe el string es solo descriptivo del contexto del test. Para evitar confusiones entre el método post y la entidad, se usa un nombre alterno como article al preparar datos para la actualización. El flujo TDD se refuerza al ejecutar las pruebas y confirmar que inicialmente fallan por rutas inexistentes, lo cual es el resultado esperado antes de implementar la lógica.

¿Qué datos requiere el payload de creación?

  • Título del post.
  • Contenido del post.
  • Publicado: valor booleano.
  • User ID: asociado al usuario creado con let y FactoryBot.

¿Cómo se valida la respuesta del método post?

  • Parseo del cuerpo: json.parse sobre response.body.
  • Estructura: el payload no debe estar vacío.
  • Identidad: el payload debe contener un ID.
  • Estado HTTP: se espera created en lugar del número, para mayor legibilidad.
  • TDD: al correr pruebas, es correcto que fallen por no encontrar la ruta de "posts".
# Creación
it 'It should create a post' do
  # payload con título, contenido, publicado: false, user_id.
  post 'posts', params: payload

  parsed = json.parse(response.body)
  expect(parsed).not_to be_empty
  expect(parsed).to include('id')
  expect(response).to have_http_status(:created)
end

¿Cómo se prueba la actualización con put sin confusiones?

Para actualizar se necesita un post existente. Se crea con FactoryBot y, para no confundir con el método post, se nombra la variable como article. El payload de actualización puede cambiar título, contenido y publicado (por ejemplo, a true). El user ID no se actualiza. Se envía put con el ID del recurso, se parsea la respuesta y se aseguran las condiciones clave: contenido no vacío, ID igual al existente y estado HTTP ok.

Al ejecutar, las pruebas deben fallar si la ruta put no existe aún. Esto confirma el ciclo TDD: primero rojo, luego la implementación.

¿Qué estados HTTP se comprueban y por qué?

  • Creación con post: estado created para indicar que el recurso se creó.
  • Actualización con put: estado ok para indicar éxito en la modificación.
  • Legibilidad: se pueden usar identificadores en lugar de números.
# Actualización
it 'actualiza el artículo existente' do
  # article existente
  put "posts/:id", params: payload_actualizado

  parsed = json.parse(response.body)
  expect(parsed).not_to be_empty
  expect(parsed['id']).to eq(article.id)
  expect(response).to have_http_status(:ok)
end

¿Cómo se manejan errores y validaciones en creación y actualización?

Se añaden pruebas negativas para confirmar respuestas y mensajes de error. En creación, un título vacío debe devolver estado HTTP unprocessable entity, sin ID y con una llave de error no vacía. En actualización, un payload con título y contenido en nil también debe devolver unprocessable entity y un mensaje de error. Al correr el conjunto, es normal ver las cuatro pruebas fallar si aún no existen las rutas.

¿Qué habilidades y conceptos prácticos se aplican aquí?

  • Enfoque TDD: primero pruebas, luego implementación.
  • Métodos HTTP post y put para crear y actualizar.
  • Estructura de payload con campos mínimos.
  • Parseo de JSON con json.parse y uso de response.body.
  • Estados HTTP: created, ok, unprocessable entity.
  • Manejo de rutas y verificación de fallos iniciales.
  • Generación de datos con FactoryBot y aleatorios con Faker.
  • Asserts claros con expect y descripciones con describe y string.
  • Claridad semántica: diferenciar el método post del modelo post usando article como nombre alterno.

¿Te gustaría compartir cómo validas tus mensajes de error o qué estrategia sigues para nombrar variables y mantener claridad entre métodos HTTP y modelos?