Skip to content
IRC-CodingIRC-Coding
Test DoublesMockStubFakeDummySpyUnit Tests

Mock, Stub, Fake y Test Doubles: Objetos Sustitutos

Aprende las diferencias entre Mock, Stub, Fake, Dummy y Spy. Test Doubles simplifican pruebas aisladas y hacen tests más rápidos.

S

schutzgeist

5 min read
Mock, Stub, Fake y Test Doubles: Objetos Sustitutos

Mock, Stub, Fake y Test Doubles

Los Test Doubles son objetos sustitutos para las dependencias reales en las pruebas. Ayudan a probar componentes de forma aislada, desactivar sistemas externos y hacer que las pruebas sean deterministas. Quien comprende las diferencias entre Mock, Stub, Fake, Dummy y Spy escribe pruebas más precisas y mantenibles.

En resumen

  • Los Test Doubles reemplazan dependencias reales en las pruebas.
  • Dummy, Stub, Fake, Spy y Mock se diferencian por su comportamiento y propósito.
  • Los Mocks verifican interacciones, los Stubs entregan respuestas fijas, los Fakes contienen lógica simplificada.
  • Demasiados Mocks pueden hacer que las pruebas sean frágiles.

Descripción técnica compacta

El término Test Double proviene del concepto de doble de riesgo en el cine. Así como un actor es reemplazado por un doble, un Test Double asume el rol de una dependencia real en la prueba. El objetivo es aislar la unidad bajo prueba del mundo exterior, de modo que solo se evalúe su comportamiento.

Los cinco Test Doubles

Dummy

Un Dummy es un objeto que se pasa pero nunca se utiliza. Solo satisface las firmas de método.

Stub

Un Stub proporciona respuestas predefinidas a las llamadas. Reemplaza una dependencia real con un resultado fijo, sin contener lógica propia.

Fake

Un Fake contiene una implementación simplificada pero funcional. Un repositorio en memoria es un ejemplo típico de Fake.

Spy

Un Spy registra las llamadas para poder verificarlas después. Es una variante artesanal de un Mock.

Mock

Un Mock es un objeto en el que las interacciones esperadas se definen antes de la prueba. Después de la prueba, se verifica si esas llamadas realmente ocurrieron.

Ejemplo práctico: procesamiento de pedidos con Test Doubles

from unittest.mock import Mock

class OrderService:
    def __init__(self, payment_gateway, inventory_repository):
        self.payment_gateway = payment_gateway
        self.inventory_repository = inventory_repository

    def process_order(self, order):
        available = self.inventory_repository.is_available(order.product_id)
        if not available:
            return {"status": "failed", "reason": "out_of_stock"}
        payment_result = self.payment_gateway.charge(order.amount)
        if payment_result.success:
            return {"status": "success"}
        return {"status": "failed", "reason": payment_result.error}

class PaymentResult:
    def __init__(self, success, error=None):
        self.success = success
        self.error = error

def test_order_success():
    inventory = Mock()
    inventory.is_available.return_value = True

    payment = Mock()
    payment.charge.return_value = PaymentResult(success=True)

    service = OrderService(payment, inventory)
    result = service.process_order(Mock(product_id=1, amount=99.99))

    assert result["status"] == "success"
    payment.charge.assert_called_once_with(99.99)

Ventajas y desventajas

Ventajas

  • Aislamiento: Los sistemas externos y las dependencias lentas se desactivan.
  • Rapidez: Las pruebas se ejecutan sin bases de datos reales ni llamadas de red.
  • Determinismo: Los valores de retorno fijos hacen que las pruebas sean predecibles.
  • Enfoque: Solo se verifica el comportamiento de la unidad.

Desventajas

  • Falsa seguridad: Los Mocks pueden dar una imagen errónea de la realidad.
  • Carga de mantenimiento: Los Mocks estrechamente acoplados se rompen durante refactorizaciones.
  • Sobrecarga: Demasiados Test Doubles oscurecen el comportamiento real.
  • Curva de aprendizaje: Las diferencias sutiles entre Mock y Stub a menudo se entienden mal.

Puntos clave para exámenes

  • Definición y propósito de los Test Doubles.
  • Diferencias entre Dummy, Stub, Fake, Spy y Mock.
  • Cuándo se utiliza cada tipo de Double.
  • Ventajas y riesgos de los Mocks.
  • Relación con la pirámide de pruebas y las pruebas aisladas.

Preguntas típicas de examen (con respuesta breve)

  1. ¿Qué es un Test Double? Un objeto sustituto para una dependencia real en la prueba.

  2. ¿Cuál es la diferencia entre Mock y Stub? Un Stub proporciona respuestas fijas, un Mock verifica interacciones.

  3. ¿Qué es un Fake? Un sustituto con lógica simplificada pero funcional.

  4. ¿Cuándo se utiliza un Dummy? Cuando un objeto debe pasarse como parámetro pero no se utiliza en la prueba.

  5. ¿Cuál es una desventaja de los Mocks? Pueden acoplarse demasiado fuerte a la implementación y romperse durante refactorizaciones.

Fuentes principales

  1. https://martinfowler.com/bliki/TestDouble.html
  2. https://xunitpatterns.com/Test%20Double.html
  3. https://en.wikipedia.org/wiki/Test_double

Preguntas frecuentes

¿Cuál es la razón principal para usar Test Doubles?

Los Test Doubles reemplazan dependencias reales para probar un componente de forma aislada, rápida y determinista.

¿Es un Mock lo mismo que un Stub?

No. Un Stub proporciona respuestas predefinidas, mientras que un Mock define interacciones y luego las verifica.

¿Cuál es un ejemplo típico de un Fake?

Un repositorio en memoria que reemplaza una base de datos real pero que sigue siendo capaz de realizar operaciones básicas de almacenamiento y consulta.

¿Cuándo no deberías usar un Mock?

Evita los Mocks cuando la interacción real con una dependencia es el comportamiento crucial, como en consultas complejas a bases de datos.

¿Qué es un Spy?

Un Spy registra las llamadas para que puedan verificarse en la prueba. Es una alternativa manual a un Mock.

¿Qué es un Dummy?

Un Dummy es un objeto que se pasa como parámetro pero que no juega ningún papel real en la prueba.

¿Pueden los Test Doubles ocultar errores?

Sí, cuando simplifican demasiado o hacen suposiciones incorrectas sobre el comportamiento real de la dependencia.

¿Cuántos Mocks debe contener como máximo una prueba?

No hay una regla fija, pero una prueba con múltiples Mocks se vuelve compleja y frágil. Una unidad clara con pocos Doubles bien justificados es mejor.

¿Qué es Interaction Testing?

Interaction Testing verifica si un componente invoca sus dependencias de la manera esperada. Los Mocks se utilizan para esto.

¿Qué es State Testing?

State Testing verifica el resultado o el estado después de una acción, sin observar las interacciones en detalle.

¿Debo mockear APIs externas?

En pruebas unitarias sí, para lograr aislamiento y rapidez. Para pruebas de integración, es mejor preferir interfaces reales o al menos más realistas.

¿Cuál es una ventaja de los Fakes frente a los Mocks?

Los Fakes contienen lógica real aunque simplificada, y dan una imagen más realista de la dependencia que los Mocks rígidos.

¿Qué frameworks ofrecen Test Doubles?

Los frameworks comunes son Mockito para Java, unittest.mock para Python, Moq para C#, NSubstitute para .NET y jest.fn() para JavaScript.

¿Qué significa Over-Mocking?

Over-Mocking significa que una prueba simula demasiadas dependencias. Esto hace que la prueba sea frágil y poco significativa.

¿Cómo ayudan los Test Doubles a la pirámide de pruebas?

Permiten una gran cantidad de pruebas unitarias rápidas e aisladas, formando así la base amplia de la pirámide de pruebas.

Continúa en la ruta de aprendizaje de Software Testing

El siguiente artículo en la ruta de aprendizaje de Software Testing trata sobre Test Driven Development: Red, Green, Refactor — los fundamentos de TDD con el ciclo Red-Green-Refactor.

Volver al blog
Share:

Entradas relacionadas