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.rbrequire'rails_helper'RSpec.describe 'Posts',type::requestdo 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
endend 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)endendend 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)endendend
¿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.rbFactoryBot.define do factory :userdo email { Faker::Internet.email } name { Faker::Name.name } auth_token {'my_string'}endend
# spec/factories/posts.rbFactoryBot.define do factory :postdo title { Faker::Lorem.sentence } content { Faker::Lorem.paragraph } published { r = rand(0..1) r ==0?false:true} user
endend
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:
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.