DEV Community

Cover image for Cómo Simular una API para Pruebas: Guía Práctica
Roobia
Roobia

Posted on • Originally published at apidog.com

Cómo Simular una API para Pruebas: Guía Práctica

Las pruebas que dependen de una API en vivo fallan por motivos externos a tu código: un servidor de prueba caído, un rate limit de terceros, datos modificados por otro equipo o una respuesta lenta. Simular la API elimina esa fragilidad: sustituyes el endpoint real por un mock controlado que devuelve la respuesta que necesitas, de forma repetible.

Prueba Apidog hoy

En esta guía vas a implementar un flujo práctico para simular una API en pruebas: definir el esquema, generar respuestas mock, levantar un servidor de simulación, apuntar tus tests al mock y cubrir rutas de error difíciles de reproducir con un backend real. Usaremos una API pequeña de gestión de pedidos con el endpoint GET /orders/{id}, pero el patrón aplica a cualquier API REST o GraphQL.

Cuándo simular la API

Simula la API cuando quieres probar tu propio código, no la red ni el backend real.

Casos típicos:

  • Tests unitarios de clientes HTTP.
  • Tests de integración de frontend/backend contra contratos conocidos.
  • Validación de parsing de respuestas.
  • Manejo de errores como 404, 429, 500 o timeouts.
  • Pruebas de retry, fallback y mensajes de error.

Mantén la API real para:

  • Pruebas de contrato.
  • Una capa pequeña de end-to-end.
  • Verificaciones periódicas contra producción o staging.

La división práctica es:

  • Mock: velocidad, aislamiento y control.
  • API real: confirmar que el contrato sigue siendo válido.

Para profundizar, revisa estos recursos sobre escenarios donde la simulación de API vale la pena y la diferencia entre un servidor simulado y un servidor real.

Flujo de trabajo en cinco pasos

Simular una API para pruebas suele seguir el mismo proceso:

  1. Define el esquema de la API.
  2. Genera respuestas simuladas estáticas o dinámicas.
  3. Ejecuta un servidor de simulación accesible por URL.
  4. Apunta tus pruebas al mock usando una URL base configurable.
  5. Prueba rutas de error que el backend real no expone bajo demanda.

El ejemplo base será:

GET /orders/{id}
Enter fullscreen mode Exit fullscreen mode

Paso 1: Define el esquema

Un mock solo es útil si respeta la forma real de la respuesta. Empieza por un contrato. Si ya tienes un documento OpenAPI, úsalo. Si no, define el endpoint que vas a probar.

Ejemplo mínimo para GET /orders/{id}:

paths:
  /orders/{id}:
    get:
      parameters:
        - name: id
          in: path
          required: true
          schema: { type: string }
      responses:
        '200':
          content:
            application/json:
              schema:
                type: object
                properties:
                  id: { type: string }
                  status: { type: string, enum: [pending, shipped, delivered] }
                  total: { type: number }
                  items: { type: array, items: { type: object } }
        '404':
          description: Order not found
Enter fullscreen mode Exit fullscreen mode

Este esquema te da dos beneficios:

  • El mock sabe qué campos debe devolver.
  • Tus tests tienen una fuente de verdad compartida con el backend.

Cuando el contrato cambia, actualizas el esquema y regeneras las respuestas mock desde ahí. Esa disciplina es clave para mantener confiables las pruebas de contrato de API.

Paso 2: Genera respuestas simuladas

Puedes usar dos tipos de respuestas.

Respuestas estáticas

Son payloads JSON fijos. Úsalas cuando necesitas aserciones exactas.

Ejemplo:

{
  "id": "order_8842",
  "status": "shipped",
  "total": 149.99,
  "items": [
    {
      "sku": "sku_keyboard",
      "quantity": 1
    },
    {
      "sku": "sku_mouse",
      "quantity": 1
    }
  ]
}
Enter fullscreen mode Exit fullscreen mode

Son ideales para tests como:

expect(order.status).toBe('shipped');
expect(order.total).toBe(149.99);
Enter fullscreen mode Exit fullscreen mode

Respuestas dinámicas

Se generan por solicitud. En lugar de devolver siempre el mismo total, el mock puede producir valores realistas:

  • UUIDs para id.
  • Un valor válido del enum para status.
  • Cantidades monetarias plausibles para total.
  • Arrays con tamaños variables.

Esto ayuda a detectar errores que un fixture único puede ocultar, por ejemplo:

  • Parsers que fallan con strings largos.
  • Campos opcionales ausentes.
  • Arrays vacíos.
  • Valores nulos inesperados.

La mayoría de equipos combina ambas estrategias:

  • Estáticas para tests deterministas.
  • Dinámicas para cobertura más amplia.

Con Apidog, puedes generar endpoints mock desde el esquema. Apidog interpreta nombres de campos como email, phone o avatar y devuelve datos acordes al tipo esperado.

Si escribes payloads a mano, evita fixtures demasiado artificiales como:

{
  "id": "1",
  "status": "pending",
  "total": 0,
  "items": []
}
Enter fullscreen mode Exit fullscreen mode

Mejor usa datos parecidos a producción:

{
  "id": "order_8842",
  "status": "shipped",
  "total": 149.99,
  "items": [
    {
      "sku": "sku_keyboard",
      "name": "Mechanical Keyboard",
      "quantity": 1,
      "price": 99.99
    },
    {
      "sku": "sku_mouse",
      "name": "Wireless Mouse",
      "quantity": 1,
      "price": 50
    }
  ]
}
Enter fullscreen mode Exit fullscreen mode

Paso 3: Ejecuta el servidor de simulación

Una respuesta mock necesita servirse desde una URL. Tienes dos opciones principales.

Opción A: servidor mock local

Úsalo para tests unitarios e integración local. Es rápido, no depende de red externa y evita estado compartido.

Con Prism, puedes levantar un mock desde un archivo OpenAPI:

prism mock openapi.yaml
# Mock server listening on http://127.0.0.1:4010
Enter fullscreen mode Exit fullscreen mode

Luego puedes probarlo con curl:

curl http://127.0.0.1:4010/orders/order_8842
Enter fullscreen mode Exit fullscreen mode

Opción B: servidor mock en la nube

Úsalo cuando el mock debe ser accesible desde:

  • Una app móvil.
  • Un runner de CI.
  • Un colaborador externo.
  • Otro equipo sin acceso a tu máquina.

Apidog ofrece una URL de simulación alojada por proyecto, útil para compartir el mismo endpoint mock entre varias personas o dispositivos.

Para ejecución automatizada de tests, prefiere local cuando sea posible. Para demos, pruebas entre dispositivos o colaboración remota, usa mock en la nube.

Paso 4: Apunta tus pruebas al mock

No hardcodees la URL de producción en tus tests. Haz que la URL base sea configurable.

Ejemplo de cliente:

// orderClient.js
export async function getOrder(id, baseUrl) {
  const response = await fetch(`${baseUrl}/orders/${id}`);

  if (response.status === 404) {
    throw new Error(`Order ${id} not found`);
  }

  if (!response.ok) {
    throw new Error(`Unexpected API error: ${response.status}`);
  }

  return response.json();
}
Enter fullscreen mode Exit fullscreen mode

Test apuntando al mock:

// orderClient.test.js
import { getOrder } from './orderClient.js';

const BASE_URL = process.env.API_BASE_URL || 'http://127.0.0.1:4010';

test('parses a shipped order', async () => {
  const order = await getOrder('order_8842', BASE_URL);

  expect(order.status).toBe('shipped');
  expect(typeof order.total).toBe('number');
  expect(Array.isArray(order.items)).toBe(true);
});
Enter fullscreen mode Exit fullscreen mode

En local:

API_BASE_URL=http://127.0.0.1:4010 npm test
Enter fullscreen mode Exit fullscreen mode

En CI puedes apuntar la misma suite a otro entorno:

API_BASE_URL=https://mock.example.com npm test
Enter fullscreen mode Exit fullscreen mode

El código de producción no necesita saber si está usando un mock o una API real. Solo recibe una URL base. Este mismo patrón aplica cuando automatizas las pruebas de API en CI/CD.

Paso 5: Prueba las rutas de error

Este es el mayor valor de un mock: puedes forzar respuestas que un backend real no produce cuando tú quieres.

Configura escenarios como estos:

Escenario La simulación devuelve Qué verificas
Registro faltante 404 El cliente lanza un error claro de "no encontrado"
Fallo del servidor 500 El cliente reintenta y luego usa un fallback
Rate limit 429 con Retry-After El cliente espera el tiempo correcto
Respuesta lenta 200 después de 5s El cliente aplica timeout y se recupera
Cuerpo inválido 200 con JSON defectuoso El cliente falla sin crashear

Ejemplo de test para 404:

test('throws a clear error when order does not exist', async () => {
  await expect(getOrder('order_404', BASE_URL))
    .rejects
    .toThrow('Order order_404 not found');
});
Enter fullscreen mode Exit fullscreen mode

Ejemplo de test para 500 con retry:

test('retries when the API returns 500', async () => {
  const order = await getOrderWithRetry('order_retry', BASE_URL, {
    retries: 2
  });

  expect(order.id).toBe('order_retry');
});
Enter fullscreen mode Exit fullscreen mode

Las reglas avanzadas de simulación de Apidog permiten devolver respuestas distintas según la solicitud. Por ejemplo:

  • GET /orders/order_404 devuelve 404.
  • GET /orders/order_timeout responde con retraso.
  • GET /orders/order_8842 devuelve 200.

Así puedes cubrir la ruta feliz y los fallos desde un único endpoint mock. Combínalo con buenas aserciones de API para verificar comportamiento, no solo códigos de estado.

Organiza los mocks en una suite creciente

Un mock para un endpoint es fácil. Cien mocks repartidos en una suite se vuelven difíciles de mantener si no hay estructura.

Buenas prácticas:

Agrupa por servicio real

Organiza los mocks según el servicio que representan:

mocks/
  orders/
    order-shipped.json
    order-not-found.json
    order-rate-limited.json
  payments/
    payment-approved.json
    payment-declined.json
Enter fullscreen mode Exit fullscreen mode

No los agrupes por test individual. Si cambia la API de pedidos, quieres actualizar una carpeta, no veinte archivos dispersos.

Nombra fixtures por escenario

Usa nombres que expliquen el caso:

order-shipped.json
order-delivered.json
order-not-found.json
order-rate-limited.json
Enter fullscreen mode Exit fullscreen mode

Así, cuando falle un test, el fixture ya comunica la intención.

Versiona los mocks junto a los tests

Los mocks son parte de la prueba. Deben pasar por code review igual que el código de test.

Usa una respuesta base

Evita copiar payloads completos para cada test. Define una respuesta base y cambia solo el campo relevante.

Ejemplo:

const baseOrder = {
  id: 'order_8842',
  status: 'shipped',
  total: 149.99,
  items: [
    { sku: 'sku_keyboard', quantity: 1 },
    { sku: 'sku_mouse', quantity: 1 }
  ]
};

const pendingOrder = {
  ...baseOrder,
  status: 'pending'
};
Enter fullscreen mode Exit fullscreen mode

Este enfoque reduce duplicación y hace que los cambios de contrato sean más fáciles de aplicar. La misma disciplina que mantiene una suite de pruebas para la automatización de API también mantiene sanos tus mocks.

Mantén la simulación alineada con la API real

El riesgo principal de un mock es la deriva del contrato.

Ejemplos:

  • El backend renombra total a amount.
  • Se agrega un campo obligatorio.
  • Cambia un enum.
  • Un campo deja de aceptar null.
  • La estructura de items cambia.

Si tus mocks no se actualizan, la suite puede seguir en verde mientras producción falla.

Para evitarlo:

1. Genera mocks desde el mismo esquema

Usa el mismo OpenAPI que publica el backend. Si el contrato cambia, el mock debe regenerarse desde esa fuente.

2. Ejecuta pruebas de contrato contra la API real

Mantén una suite pequeña que valide que la API viva sigue respetando el esquema.

Ejemplo de estrategia:

tests/
  unit/           -> usan mock local
  integration/    -> usan mock local o mock cloud
  contract/       -> usan API real de staging
  e2e/            -> usan API real con pocos casos críticos
Enter fullscreen mode Exit fullscreen mode

3. Revisa mocks en cada pull request

Si una PR cambia una respuesta de API, debe cambiar también:

  • El esquema OpenAPI.
  • Los fixtures mock.
  • Las pruebas afectadas.

Trata la simulación como parte del contrato, no como un helper temporal.

Si quieres un entorno que concentre esquema, mock server y pruebas, puedes descargar Apidog. También puedes comparar alternativas en esta lista de herramientas de simulación de API REST.

Preguntas frecuentes

¿Debería simular la API para cada prueba?

No. Simula en pruebas unitarias e integración cuando estás validando tu propio código. Mantén un conjunto pequeño de pruebas de contrato y end-to-end contra la API real para confirmar que el mock sigue alineado con producción.

¿Cuál es la diferencia entre una respuesta mock estática y dinámica?

Una respuesta estática es un JSON fijo y predecible. Es útil para aserciones exactas.

Una respuesta dinámica se genera por solicitud con valores realistas. Es útil para descubrir errores que un único fixture no detectaría.

Lo habitual es usar ambas.

¿Cómo aseguro que mi mock siga siendo preciso?

Genera el mock desde el mismo esquema que usa el backend, idealmente OpenAPI. Luego ejecuta pruebas de contrato programadas contra la API real. Si esas pruebas fallan, el contrato o el mock deben actualizarse.

¿Puede un mock simular respuestas lentas o fallidas?

Sí. Puedes configurar respuestas como:

  • 500 Internal Server Error.
  • 429 Too Many Requests con Retry-After.
  • 200 OK con retraso.
  • JSON mal formado.
  • Timeouts.

Esto permite probar lógica de retries, fallback y manejo de errores sin romper un backend real.

¿Servidor mock local o en la nube?

Usa mock local para ejecuciones de test: es rápido, aislado y sin latencia externa.

Usa mock en la nube cuando necesites acceso desde una app móvil, CI remoto, otro equipo o colaboradores externos.

Top comments (0)