[英]Python: how can I override a complicated function during unittest?
我正在使用Python的unittest
模块来测试正在编写的脚本。
该脚本包含如下循环:
// my_script.py
def my_loopy_function():
aggregate_value = 0
for x in range(10):
aggregate_value = aggregate_value + complicated_function(x)
return aggregate_value
def complicated_function(x):
a = do()
b = something()
c = complicated()
return a + b + c
我使用没有问题unittest
来测试complicated_function
。 不过,我想测试my_loopy_function
通过重写complicated_function
。
我试图修改我的脚本,以便my_loopy_function
需要complicated_function
作为可选参数,这样我可以从测试的简单版本通过:
// my_modified_script.py
def my_loopy_function(action_function=None):
if action_function is not None:
complicated_function = action_function
aggregate_value = 0
for x in range(10):
aggregate_value = aggregate_value + complicated_function(x)
return aggregate_value
def complicated_function(x):
a = do()
b = something()
c = complicated()
return a + b + c
// test_my_script.py
from myscript import my_loopy_function
class TestMyScript(unittest.TestCase):
test_loopy_function(self):
def simple_function():
return 1
self.assertEqual(10, my_loopy_function(action_function=simple_function))
它没有按我希望的那样工作,是否有关于如何进行此操作的建议?
不要试图重写complicated_function
与action_function
,只需使用complicated_function
作为默认action_function
:
def my_loopy_function(action_function=complicated_function):
aggregate_value = 0
for x in range(10):
aggregate_value = aggregate_value + action_function(x)
return aggregate_value
最后,我使用了Python的mock
,它使我可以覆盖complicated_function
而不必以任何方式调整原始代码。
这里是原始脚本,并注意complicated_function
不传递给my_loopy_function
作为“ action_function
”参数(这是我在我的早期解决方案试过):
// my_script.py
def my_loopy_function():
aggregate_value = 0
for x in range(10):
aggregate_value = aggregate_value + complicated_function(x)
return aggregate_value
def complicated_function(x):
a = do()
b = something()
c = complicated()
return a + b + c
这是我用来测试的脚本:
// test_my_script.py
import unittest
import mock
from my_script import my_loopy_function
class TestMyModule(unittest.TestCase):
@mock.patch('my_script.complicated_function')
def test_1(self, mocked):
mocked.return_value = 1
self.assertEqual(10, my_loopy_function())
就像我想要的那样工作:
mock
模块使我可以对内部对象进行后期编码访问。 感谢奥斯丁提出的使用mock
建议。 顺便说一句,我正在使用Python 2.7,因此使用了PyPI的pip
-installable mock
。
在您的代码中,您不应该能够像这样覆盖complicated_function
。 如果尝试,我会UnboundLocalError: local variable 'complicated_function' referenced before assignment
得到UnboundLocalError: local variable 'complicated_function' referenced before assignment
。
但是,也许是这样的问题:在您的实际代码中,您是以其他方式(例如,作为模块的成员)引用了complicated_function
吗? 然后通过在测试中覆盖它,就覆盖了实际的complicated_function
,因此您将无法在其他测试中使用它。
正确的方法是用全局变量覆盖局部变量,如下所示:
def my_loopy_function(action_function=None):
if action_function is None:
action_function = complicated_function
aggregate_value = 0
for x in range(10):
# Use action_function here instead of complicated_function
aggregate_value = aggregate_value + action_function(x)
return aggregate_value
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.