Под «внутренней функцией» я подразумеваю функцию, которая вызывается из того же модуля, в котором она определена.
Я использую библиотеку mock , в частности, декораторы patch , в моих модульных тестах. Это модульные тесты Django, но они должны применяться к любым тестам на Python.
У меня есть один модуль с несколькими функциями, многие из которых вызывают друг друга. Например (вымышленный код, игнорируйте отсутствие десятичного. Десятичного):
TAX_LOCATION = 'StateName, United States'
def add_tax(price, user):
tax = 0
if TAX_LOCATION == 'StateName, UnitedStates':
tax = price * .75
return (tax, price+tax)
def build_cart(...):
# build a cart object for `user`
tax, price = add_tax(cart.total, cart.user)
return cart
Это часть более глубокой цепочки вызовов (func1 -> func2 -> build_cart -> add_tax), все из которых находятся в одном модуле.
В моих модульных тестах я хотел бы отключить налоги, чтобы получить согласованные результаты. На мой взгляд, у меня есть два варианта: 1) исправить TAX_LOCATION (скажем, с пустой строкой), чтобы add_tax ничего не делал, или 2) исправить add_tax для простого возврата (0, цена).
Однако, когда я пытаюсь исправить одно из этих исправлений, кажется, что исправление работает внешне (я могу импортировать исправленную часть внутри теста и распечатать его, получая ожидаемые значения), но, похоже, не имеет никакого внутреннего эффекта ( получить из кода вести себя так, как будто патч не был применен).
Мои тесты такие (опять же, вымышленный код):
from mock import patch
from django.test import TestCase
class MyTests(TestCase):
@patch('mymodule.TAX_LOCATION', '')
def test_tax_location(self):
import mymodule
print mymodule.TAX_LOCATION # ''
mymodule.func1()
self.assertEqual(cart.total, original_price) # fails, tax applied
@patch('mymodule.add_tax', lambda p, u: (0, p))
def test_tax_location(self):
import mymodule
print mymodule.add_tax(50, None) # (0, 50)
mymodule.func1()
self.assertEqual(cart.total, original_price) # fails, tax applied
Кто-нибудь знает, возможно ли в mock исправлять такие функции, используемые внутри компании, или мне не повезло?