0Pricing
Python Academy · Lección

Simulación con unittest.mock

Aísle las unidades que se están probando simulando sus dependencias.

Simulación con unittest.mock es una lección gratuita de Python Academy en CoddyKit. Esta es la lección 4 de 4. Puedes leer la lección completa abajo gratuitamente — luego la practicas en el navegador con un editor de código integrado y un tutor de IA 24/7. Forma parte de la ruta de aprendizaje de Python Academy, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de Python Academy incluye 4 lecciones en total.

¿Por qué usar mocks?

Los mocks sustituyen dependencias reales (bases de datos, API y sistema de archivos) por dobles controlables, de modo que las pruebas se ejecutan rápidamente, de forma determinista y aislada.

from unittest.mock import Mock

api = Mock()
api.get_user.return_value = {"id": 1, "name": "Alice"}

result = api.get_user(1)
print(result)  # {'id': 1, 'name': 'Alice'}

Mock y MagicMock

Mock es la clase base. MagicMock configura automáticamente los métodos mágicos o dunder, por lo que puede usarse como iterador, gestor de contexto, etc.

from unittest.mock import MagicMock

m = MagicMock()
m.__len__.return_value = 5
print(len(m))  # 5

m.__iter__.return_value = iter([1, 2, 3])
for x in m:
    print(x)

patch como decorador

Use @patch para sustituir un objeto de un módulo por un mock durante la prueba.

from unittest.mock import patch

def get_data():
    import requests
    return requests.get("https://api.example.com").json()

@patch("requests.get")
def test_get_data(mock_get):
    mock_get.return_value.json.return_value = {"key": "value"}
    result = get_data()
    assert result == {"key": "value"}

patch como gestor de contexto

Use patch() como gestor de contexto para aplicar el mocking de forma más localizada.

from unittest.mock import patch

def test_open():
    with patch("builtins.open", create=True) as mock_open:
        mock_open.return_value.__enter__.return_value.read.return_value = "data"
        with open("file.txt") as f:
            assert f.read() == "data"

patch.object

patch.object(target, attribute) aplica un patch a un atributo específico de un objeto o clase existente.

from unittest.mock import patch
import mymodule

def test_method():
    with patch.object(mymodule.MyClass, "fetch", return_value=42):
        obj = mymodule.MyClass()
        assert obj.fetch() == 42

Comprobación de llamadas

Los mocks registran cada llamada. Use assert_called_once_with, assert_called_with y call_count para verificar el comportamiento.

from unittest.mock import Mock

send = Mock()
send("hello", to="alice")

send.assert_called_once_with("hello", to="alice")
print(send.call_count)  # 1

return_value y side_effect

Establezca return_value para controlar qué devuelve el mock. Use side_effect para lanzar excepciones o devolver valores diferentes en llamadas sucesivas.

from unittest.mock import Mock

m = Mock(side_effect=[1, 2, ValueError("done")])
print(m())  # 1
print(m())  # 2
m()         # raises ValueError

spec: mocks seguros con tipos

Pase spec=MyClass para limitar el mock únicamente a los atributos que existen en la clase real.

from unittest.mock import Mock

class Calc:
    def add(self, a, b): return a + b

m = Mock(spec=Calc)
m.add(1, 2)         # OK
# m.subtract(1, 2)  # AttributeError: Mock does not have 'subtract'

patch.dict

Use patch.dict para modificar temporalmente un diccionario (por ejemplo, variables de entorno o configuraciones a nivel de módulo).

from unittest.mock import patch
import os

def test_env():
    with patch.dict(os.environ, {"DEBUG": "true"}):
        assert os.environ["DEBUG"] == "true"
    assert "DEBUG" not in os.environ

Mock en pytest con pytest-mock

pytest-mock proporciona un fixture mocker que envuelve unittest.mock y realiza automáticamente la limpieza después de cada prueba.

# pip install pytest-mock

def test_service(mocker):
    mocker.patch("mymodule.requests.get", return_value=mocker.Mock(
        json=lambda: {"status": "ok"}
    ))
    from mymodule import call_api
    assert call_api()["status"] == "ok"

AsyncMock para corrutinas

Use AsyncMock para simular funciones asíncronas a las que se aplica await.

from unittest.mock import AsyncMock, patch
import asyncio

async def fetch():
    import httpx
    async with httpx.AsyncClient() as c:
        r = await c.get("https://example.com")
        return r.json()

def test_fetch():
    with patch("httpx.AsyncClient.get", new_callable=AsyncMock) as m:
        m.return_value.json.return_value = {"ok": True}
        result = asyncio.run(fetch())
        assert result["ok"] is True

Comprobación rápida

¿Qué atributo debe establecer en un Mock para controlar qué valor devuelve al llamarlo?

Resumen

unittest.mock proporciona Mock, MagicMock, patch y AsyncMock. Use return_value y side_effect para controlar el comportamiento, y métodos de aserción para verificar cómo se llamaron los mocks.

Preguntas frecuentes

¿La lección «Simulación con unittest.mock» es gratis?

Sí — el texto completo de «Simulación con unittest.mock» es gratis para leer aquí en la web. Para practicarla de forma interactiva (editor de código integrado y tutor de IA 24/7) y desbloquear el resto del curso de Python Academy, actualiza a CoddyKit PRO. El curso de Python Academy incluye 4 lecciones en total.

¿Qué aprenderé en «Simulación con unittest.mock»?

Aísle las unidades que se están probando simulando sus dependencias. Practicas Python Academy con código real que ejecutas directamente en el navegador, y un tutor de IA 24/7 responde tus preguntas mientras trabajas en la lección.

¿Necesito experiencia previa para empezar Python Academy?

No se requiere experiencia previa. Python Academy en CoddyKit está estructurado para principiantes hasta estudiantes avanzados, así que puedes empezar aquí o desde el inicio y avanzar a tu ritmo. Esta es la lección 4 de 4.

¿Cuánto tiempo toma la lección «Simulación con unittest.mock»?

La mayoría de las lecciones de CoddyKit toman alrededor de 5–10 minutos. Cada una es compacta e interactiva, así que avanzas constantemente y retomas exactamente por donde dejaste en la web y la app.

¿Puedo escribir y ejecutar código en esta lección de Python Academy?

Sí. Cada lección de Python Academy incluye un editor de código integrado, así que escribes y ejecutas código real directamente en tu navegador y obtienes retroalimentación instantánea de IA — sin configuración local necesaria.

Todas las lecciones de este curso

  1. Escritura de sus primeras pruebas con pytest
  2. Fixtures y configuración/desmontaje
  3. Parametrización y cobertura de pruebas
  4. Simulación con unittest.mock
← Volver a Python Academy