我所说的“内部函数”是指从定义它的同一模块内调用的函数。
我正在使用mock http://www.voidspace.org.uk/python/mock/图书馆,特别是patch http://www.voidspace.org.uk/python/mock/patch.html装饰器,在我的单元测试中。它们是 Django 单元测试,但这应该适用于任何 python 测试。
我有一个具有多个函数的模块,其中许多函数相互调用。例如(虚构代码,忽略缺少decimal.Decimal):
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
有谁知道模拟是否可以修补像这样内部使用的函数,或者我运气不好?