python - tutorial - Comment se moquer d'une fonction décorée



python mock__init__ (1)

Pour des raisons de test, je dois pouvoir me moquer de la fonction interne / originale d'une fonction décorée qui est utilisée ailleurs:

Dans 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()

Comme vous pouvez le voir, j'ai plusieurs versions de la fonction originale function_to_be_mocked, une avec le décorateur my_decorator et une autre 'naked'. La fonction runner run_decorated () appelle la version décorée de function_to_be_mocked et run_undecorated () appelle la version non décorée et applique le décorateur 'manuellement'. Le résultat des deux est le même:

decorated
original

Maintenant, je veux tester la fonction runner mais je dois me moquer de la fonction originale function_to_be_mocked mais aussi la version mockée devrait être décorée:

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

Cela fonctionne comme prévu pour la version non décorée test_undecorated_mocked:

decorated
mockified

Mais la version décorée donne:

mockified

alors le décorateur a disparu.

Est-il possible de faire fonctionner la version décorée de la même manière que la version non décorée, où le décorateur est appliqué «manuellement»?

J'ai essayé d'exposer la fonction intérieure dans le décorateur sans succès.

J'ai vu cette question Comment vous vous moquez d'une fonction à laquelle un décorateur s'applique dans un test unitaire? mais cela ne m'aide pas.


Python applique le décorateur lors du chargement du module, donc la définition de function_to_be_mocked sur mock_function dans test_decoratorated_mocked changerait en effet cette fonction en fonction non décorée.

Vous auriez besoin d'ajouter manuellement le décorateur si vous souhaitez simuler function_to_be_mocked :

mydecorator.function_to_be_mocked = mydecorator.my_decorator(mock_function)




monkeypatching