Saltar al contenido

Python Mock Patch múltiples métodos en una clase

Solución:

Lo que necesitas es:

burlarse de la clase Hook,

from HookTransfer import HookTransfer
from Hook import Hook

import unittest
try:
    import mock
except ImportError:
    from unittest import mock

class TestMock(unittest.TestCase):
    @mock.patch.object(Hook, 'get_key', return_value="New_Key")
    @mock.patch.object(Hook, 'get_value', return_value="New_Value")
    def test_execute1(self, mock_get_key, mock_get_value):
        HookTransfer().execute()

if __name__ == "__main__":
    unittest.main()

Puede parchear varios métodos de un módulo o una clase usando patch.multiple(). Algo como esto debería funcionar para su caso:

import unittest
from unittest.mock import MagicMock, patch

class TestMock(unittest.TestCase):
    @patch.multiple('HookTransfer.Hook',
                    get_key=MagicMock(return_value="New_Key"),
                    get_value=MagicMock(return_value="New_Value"))
    def test_execute1(self, **mocks):
        HookTransfer().execute()

Cuando patch.multiple() se usa como decorador, los simulacros se pasan a la función decorada por palabra clave y se devuelve un diccionario cuando se usa como administrador de contexto.

Después de algunas pruebas, pude encontrar el problema.

En el segundo caso de prueba, el decorador de parches crea una nueva instancia de una clase Mock y la pasa a través del argumento mock_hook a la función test_execute2. Vamos a referirnos a esto como mock1. mock1 reemplaza la clase Hook en HookTransfer.py. Cuando self.hook = Hook() se ejecuta, se traduce en llamar __init__ de mock1. Por diseño, esto devuelve otra instancia de Mock; nos referiremos a esto como mock2. Así que self.hook apunta a mock2. Pero mock_hook.get_key = mock.Mock(return_value="New_Key"), se burla de los métodos en mock1.

Para simular correctamente, mock2 necesita ser parcheado. Esto se puede hacer de 2 formas

  1. Burlándose del return_value de mock1 (que devuelve mock2) mock_hook.return_value.get_key = mock.Mock(return_value="New_Key")
  2. Burlarse del valor de retorno del constructor de mock1 (que devuelve mock2) mock_hook().get_key = mock.Mock(return_value="New_Key")

Debajo de las envolturas, ambas opciones realmente hacen lo mismo.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *