Należy zauważyć, że kilka z przedstawionych tutaj odpowiedzi załatuje dekorator dla całej sesji testowej, a nie dla jednej instancji testowej; co może być niepożądane. Oto jak załatać dekorator, który utrzymuje się tylko przez jeden test.
Nasza jednostka do przetestowania z niepożądanym dekoratorem:
from app.decorators import func_decor
@func_decor
def unit_to_be_tested():
pass
Z modułu dekoratorów:
def func_decor(func):
def inner(*args, **kwargs):
print "Do stuff we don't want in our test"
return func(*args, **kwargs)
return inner
Zanim nasz test zostanie zebrany podczas przebiegu testowego, niepożądany dekorator został już zastosowany do naszej testowanej jednostki (ponieważ dzieje się to w czasie importu). Aby się tego pozbyć, musimy ręcznie wymienić dekorator w module dekoratora, a następnie ponownie zaimportować moduł zawierający nasz testowany egzemplarz.
Nasz moduł testowy:
from unittest import TestCase
from app import uut
from app import decorators
import imp
from mock import patch
class TestUUT(TestCase):
def setUp(self):
def kill_patches():
patch.stopall()
imp.reload(uut)
self.addCleanup(kill_patches)
patch('app.decorators.func_decor', lambda x: x).start()
imp.reload(uut)
Wywołanie zwrotne czyszczenia, kill_patches, przywraca oryginalny dekorator i ponownie stosuje go do testowanej jednostki. W ten sposób nasza łatka utrzymuje się tylko przez jeden test, a nie przez całą sesję - i dokładnie tak powinna zachowywać się każda inna łatka. Ponadto, ponieważ czyszczenie wywołuje patch.stopall (), możemy uruchomić dowolne inne poprawki w setUp (), których potrzebujemy, i zostaną one wyczyszczone w jednym miejscu.
Ważne jest, aby zrozumieć tę metodę, jak przeładowanie wpłynie na rzeczy. Jeśli moduł trwa zbyt długo lub ma logikę działającą podczas importu, wystarczy wzruszyć ramionami i przetestować dekorator jako część jednostki. :( Mam nadzieję, że twój kod jest lepiej napisany.
Jeśli nie obchodzi nas, czy łatka zostanie nałożona na całą sesję testową , najłatwiej to zrobić bezpośrednio na górze pliku testowego:
from mock import patch
patch('app.decorators.func_decor', lambda x: x).start()
from app import uut
Pamiętaj, aby załatać plik za pomocą dekoratora, a nie lokalnego zakresu testowanego egzemplarza, i uruchomić poprawkę przed zaimportowaniem jednostki za pomocą dekoratora.
Co ciekawe, nawet jeśli łatka zostanie zatrzymana, wszystkie pliki, które zostały już zaimportowane, nadal będą miały poprawkę nałożoną na dekorator, co jest odwrotnością sytuacji, od której zaczęliśmy. Należy pamiętać, że ta metoda załatuje wszystkie inne pliki w przebiegu testowym, które są później importowane - nawet jeśli same nie deklarują poprawki.