python - example - pytest mock
Cómo burlarse de una función decorada (1)
Python aplica el decorador al cargar el módulo, por lo que establecer function_to_be_mocked
para mock_function
en test_decoratorated_mocked
cambiará esa función en una función no decorada.
Tendrá que agregar manualmente el decorador de nuevo si desea simular que function_to_be_mocked
:
mydecorator.function_to_be_mocked = mydecorator.my_decorator(mock_function)
Por razones de prueba, necesito poder burlarme de la función interior / original de una decorada que se usa en otro lugar:
En mydecorator.py:
def my_decorator(f):
def wrapped_f():
print "decorated"
f()
return wrapped_f
@my_decorator
def function_to_be_mocked():
print ''original''
def function_to_be_mocked_undecorated():
print ''original''
def run_decorated():
function_to_be_mocked()
def run_undecorated():
decorated_funtion = my_decorator(function_to_be_mocked_undecorated)
decorated_funtion()
Como puede ver, tengo varias versiones de la función original function_to_be_mocked, una con el decorador my_decorator y otra ''naked''. La función runner run_decorated () llama a la versión decorada de function_to_be_mocked y run_undecorated () llama a la versión no decorada y aplica el decorador ''manualmente''. El resultado de ambos es el mismo:
decorated
original
Ahora quiero probar la función runner pero necesito burlarme de la función original function_to_be_mocked pero también debe decorarse la versión simulada:
import unittest
import mydecorator
from mock import patch
def mock_function():
print ''mockified''
class Test(unittest.TestCase):
@patch(''mydecorator.function_to_be_mocked_undecorated'')
def test_undecorated_mocked(self, mock_function_to_be_mocked_undecorated):
mydecorator.function_to_be_mocked_undecorated = mock_function
mydecorator.run_undecorated()
assert 1==0
@patch(''mydecorator.function_to_be_mocked'')
def test_decoratorated_mocked(self, mock_function_to_be_mocked):
mydecorator.function_to_be_mocked = mock_function
mydecorator.run_decorated()
assert 1==0
Esto funciona como se esperaba para la versión no decorada test_undecorated_mocked:
decorated
mockified
Pero la versión decorada da:
mockified
entonces el decorador desapareció.
¿Es posible hacer que la versión decorada funcione del mismo modo que la versión no decorada, donde el decorador se aplica "manualmente"?
Traté de exponer la función interna en el decorador sin éxito.
Vi esta pregunta. ¿Cómo se burla de una función que tiene el decorador aplicado en una prueba unitaria? pero esto no me ayuda.