ete*_*ode 23 python patch mocking
"内部函数"是指从定义的同一模块中调用的函数.
我在单元测试中使用模拟库,特别是补丁装饰器.它们是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
Run Code Online (Sandbox Code Playgroud)
这些是更深层调用链的一部分(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
Run Code Online (Sandbox Code Playgroud)
有谁知道模拟是否可以修补这样内部使用的功能,还是我运气不好?
ete*_*ode 15
答案是:清理你的进口产品
@patch('mymodule.TAX_LOCATION', '') 确实适当修补了一些东西,但由于我们当时的进口非常随意 - 有时我们进口mymodule.build_cart,有时我们进口project.mymodule.build_cart- "完全"进口的实例根本没有修补.无论如何,模拟不能被要求知道两个单独的导入路径......没有明确说明.
我们已经在较长的路径上标准化了所有的进口,现在事情表现得更好.
另一种选择是在函数上显式调用patch:
mock.patch('function_name')
Run Code Online (Sandbox Code Playgroud)
并支持直接运行或从py.test等:
mock.patch(__name__ + '.' + 'function_name')
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
17050 次 |
| 最近记录: |