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
- Burlándose del return_value de mock1 (que devuelve mock2)
mock_hook.return_value.get_key = mock.Mock(return_value="New_Key")
- 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.