Als ich zum ersten Mal auf dieses Problem gestoßen bin, habe ich mir stundenlang den Kopf zerbrochen. Ich habe einen viel einfacheren Weg gefunden, damit umzugehen.
Dadurch wird der Dekorateur vollständig umgangen, da das Ziel überhaupt nicht dekoriert wurde.
Dies ist in zwei Teile gegliedert. Ich schlage vor, den folgenden Artikel zu lesen.
http://alexmarandon.com/articles/python_mock_gotchas/
Zwei Fallstricke, denen ich immer wieder begegnete:
1.) Verspotten Sie den Decorator vor dem Import Ihrer Funktion / Ihres Moduls.
Die Dekoratoren und Funktionen werden zum Zeitpunkt des Ladens des Moduls definiert. Wenn Sie vor dem Import nicht verspotten, wird der Schein ignoriert. Nach dem Laden müssen Sie ein seltsames mock.patch.object ausführen, das noch frustrierender wird.
2.) Stellen Sie sicher, dass Sie den richtigen Weg zum Dekorateur verspotten.
Denken Sie daran, dass der Patch des Dekorators, den Sie verspotten, davon abhängt, wie Ihr Modul den Dekorator lädt, und nicht davon, wie Ihr Test den Dekorator lädt. Aus diesem Grund empfehle ich, für den Import immer vollständige Pfade zu verwenden. Dies erleichtert das Testen erheblich.
Schritte:
1.) Die Mock-Funktion:
from functools import wraps
def mock_decorator(*args, **kwargs):
def decorator(f):
@wraps(f)
def decorated_function(*args, **kwargs):
return f(*args, **kwargs)
return decorated_function
return decorator
2.) Den Dekorateur verspotten:
2a.) Pfad nach innen mit.
with mock.patch('path.to.my.decorator', mock_decorator):
from mymodule import myfunction
2b.) Patch oben in der Datei oder in TestCase.setUp
mock.patch('path.to.my.decorator', mock_decorator).start()
Mit beiden Methoden können Sie Ihre Funktion jederzeit in den TestCase oder dessen Methode / Testfälle importieren.
from mymodule import myfunction
2.) Verwenden Sie eine separate Funktion als Nebeneffekt des mock.patch.
Jetzt können Sie mock_decorator für jeden Dekorator verwenden, den Sie verspotten möchten. Sie müssen jeden Dekorateur einzeln verspotten, achten Sie also auf diejenigen, die Sie vermissen.