[英]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.