让我们提出这个场景
# This code lives in lolcat-web/lolapps/lolburger/burger.py
import os
from helper.lib import price
def i_haz_cheezeburger(Burger, user):
kings_burgers = []
queens_burgers = []
address = os.path.join(user.hometown, burger_king_addr)
burger_menu = Burger.menu()
for burger in burger_menu:
if burger == 'King':
kings_burgers.append({
'name': burger,
'price': price(burger)
})
else:
queens_burgers.append(...)
return (kings_burgers, queens_burgers)
我想测试函数i_haz_cheezeburger
是否会返回一个元组,其中包含正确的值。这取决于一些事项(简化):os
,helper.lib.price
,Burger
和user
(用户类)
由于我对Michael Foord的mock
相当新,所以这是我的新手尝试:
修改看起来有误,因为joiner
和price
似乎没有在任何地方使用过?
def test_01(unittest.TestCase):
with patch('os.path.join') as joiner:
with patch('lolcat-web.lolapps.lolburger.burger.price') as price:
mock_user = MagicMock(name='user', spec=client.auth.User)
mock_user.hometown = 'New-York'
mock_burger = MagicMock(name='burger', spec=lolcat-web.lolapps.lolburger.Burger)
mock_burger.menu = [ '....sets up a list of samples .....' ]
# now call the function
response = i_get_cheezeburger(mock_burger, mock_user)
# now we do some assertions.....
这就像写灯具一样。如果方法i_haz_cheezeburger
具有更多依赖项,该怎么办?当然,我可以重构它们并创建一些更多的包装器/辅助函数。但问题是,或 至少 的困惑是:
我想测试我的输出。我不想知道“哦,没有错误/未绑定的赋值,因为它传递了每个定义的返回值”但是设置灯具(或者像Burger.menu
之类的返回值)听起来不对
处理此类问题的正确方法是什么?请纠正我的误解。
答案 0 :(得分:3)
不要嘲笑标准库 - 如果标准库出现问题,你就会遇到更大的问题(更不用说你几乎肯定不会整合了 - 测试标准库,因此嘲笑它只是隐藏潜在的失败。)
如果函数的输出取决于Burger.menu()
的返回值,那么如果要测试返回值,则需要为Burger.menu()
的模拟版本设置返回值。这是正确的做法。您提供的模拟输入是实际输入的受控版本,因此您希望在给定受控输入的情况下获得特定输出。使用mock
并不会从等式中神奇地删除所有实际的实际数据。