Contenido del curso

Proyecto

Implementación de Endpoints para Listar y Mostrar Posts con TDD

Resumen

El enfoque correcto con TDD en Rails te permite construir endpoints confiables desde el primer día. Aquí verás cómo diseñar pruebas con RSpec y generar datos con FactoryBot y Faker para los GET /posts y GET /posts/:id, validando el payload, el estado 200 y el comportamiento con y sin datos. La clave: escribir primero las pruebas, provocar los fallos esperados y luego implementar.

¿Cómo aplicar TDD para los endpoints de posts en Rails?

Es vital partir desde la carpeta spec y crear un nuevo spec para posts. Se plantean dos rutas: listar con GET /posts y mostrar con GET /posts/:id. Primero se copian y adaptan estructuras previas, luego se define qué debe ocurrir en cada caso: cuando no hay datos la lista debe estar vacía y el estado debe ser 200. Con datos insertados, el payload debe igualar en tamaño a lo creado y también responder 200.

¿Qué pruebas cubren listar y mostrar posts?

  • Listar sin datos: lista vacía y estado 200.
  • Listar con datos: tamaño del payload igual a los posts creados y estado 200.
  • Mostrar detalle: payload no vacío, estado 200 y el ID del payload igual al del post creado.

Ejemplo de estructura en RSpec para index y show:

# spec/requests/posts_spec.rb require 'rails_helper' RSpec.describe 'Posts', type: :request do describe 'GET /posts' do context 'sin datos en la base de datos' do it 'retorna lista vacía y 200' do get '/posts' expect(response.status).to eq(200) expect(JSON.parse(response.body)).to be_empty end end context 'con datos en la base de datos' do let(:posts) { FactoryBot.create_list(:post, 10, published: true) } it 'retorna todos los posts publicados y 200' do posts get '/posts' payload = JSON.parse(response.body) expect(response.status).to eq(200) expect(payload.size).to eq(posts.size) end end end describe 'GET /posts/:id' do it 'retorna un post y 200' do post = FactoryBot.create(:post) get "/posts/#{post.id}" payload = JSON.parse(response.body) expect(response.status).to eq(200) expect(payload['id']).to eq(post.id) end end end

¿Cómo estructurar RSpec con describe, context y let?

  • Usa describe para agrupar por ruta o acción.
  • Separa escenarios con context: "con datos" y "sin datos".
  • Declara datos con let para crear listas con FactoryBot. Esto los hace reutilizables dentro de cada prueba.

¿Cómo generar datos de prueba con FactoryBot y Faker?

Primero, genera los factories con el generador de Rails: rails g factory bot model user email:string name:string auth_token:string y luego para post con title:string content:string published:boolean user:references. Después, ajusta los valores por defecto usando Faker para que los datos sean válidos y realistas.

¿Cómo crear factories para user y post?

# spec/factories/users.rb FactoryBot.define do factory :user do email { Faker::Internet.email } name { Faker::Name.name } auth_token { 'my_string' } end end
# spec/factories/posts.rb FactoryBot.define do factory :post do title { Faker::Lorem.sentence } content { Faker::Lorem.paragraph } published { r = rand(0..1) r == 0 ? false : true } user end end

Puntos clave al crear factories:

  • Usa Faker para emails, nombres, títulos y párrafos.
  • Define published como booleano real, no nulo.
  • Declara la asociación con user para que se cree automáticamente.

¿Cómo usar datos aleatorios y asociaciones?

  • Datos aleatorios ayudan a detectar fallos por validaciones reales.
  • La asociación user en el factory de post evita tener que crear usuarios manualmente en cada prueba.

¿Cómo validar booleanos y solucionar errores comunes?

Al ejecutar las pruebas y la consola en el entorno de pruebas con la variable de entorno de Rails, se detectó un error típico: el validador de presencia marca false como vacío en atributos booleanos. Por eso, aunque published estaba en false, se consideraba inválido.

¿Por qué presence falla con booleanos?

  • El validador de presence trata false como valor vacío.
  • Con booleanos, false puede ser un estado válido y debe aceptarse.

¿Qué cambio hacer con inclusion para published?

Reemplaza la presencia por inclusión explícita en booleanos:

# app/models/post.rb class Post < ApplicationRecord validates :published, inclusion: { in: [true, false] } end

Además, ajusta la prueba del modelo para no requerir presencia en published. Tras este cambio, las fallas se reducen a lo esperado por TDD: rutas inexistentes aún por implementar en el controlador.

¿Quieres que revisemos la implementación del controlador y las rutas para que las pruebas pasen? Deja tus preguntas y comenta qué parte te interesa profundizar.