不想手动测试我的代码,我试图编写一个模拟/修补我的依赖项的测试(PyInquirer是一个非常简洁的程序包,可以为我处理CLI-输入问题,回答问题)。
但是,对于Python来说是一个新手,我在模拟该依赖项时遇到了困难。这是我正在测试的代码:
from PyInquirer import prompt
class Foo:
def bar(self):
# this line is asking the user for inpit, and that's what I want to mock.
a = prompt({'name': 'q',
'type': 'input',
'message': 'well, foo'})
print("f is", f)
return a
这是测试:
import unittest
from unittest.mock import patch
from Foo import Foo
class TestFoo(unittest.TestCase):
@patch('PyInquirer.prompt', return_value=24)
def test_bar(self):
f = Foo()
a = f.bar()
assert a == 24
if __name__ == '__main__':
unittest.main()
(实际代码显然要复杂得多,但这是问题的本质)。表现为:
Error
Traceback (most recent call last):
File "/usr/local/Cellar/python/3.6.5_1/Frameworks/Python.framework/Versions/3.6/lib/python3.6/unittest/case.py", line 59, in testPartExecutor
yield
File "/usr/local/Cellar/python/3.6.5_1/Frameworks/Python.framework/Versions/3.6/lib/python3.6/unittest/case.py", line 605, in run
testMethod()
File "/usr/local/Cellar/python/3.6.5_1/Frameworks/Python.framework/Versions/3.6/lib/python3.6/unittest/mock.py", line 1179, in patched
return func(*args, **keywargs)
TypeError: test_bar() takes 1 positional argument but 2 were given
我很困惑。
如果我省略了补丁装饰器,则调用将失败,并出现预期的断言错误-提示生成的字典不等于24。但是,如果我确实提供了装饰器,则上面会出现参数不匹配的情况。确实,stacktrace的最后一行确实显示了函数“ func”,我认为这是装饰器所应用的函数,它使用两个参数来调用……但是……为什么呢?难道不是问题的本质吗?这样只能修补两个偶数的函数=)
答案 0 :(得分:2)
您的课程使用名称Foo.prompt
(由于您的导入方式),所以这就是您需要修补的。
class TestFoo(unittest.TestCase):
@patch('Foo.prompt', return_value=24)
def test_bar(self, mock_prompt):
f = Foo()
a = f.bar()
assert a == 24
您还需要向test_bar
添加参数以接收修补的对象,无论您是否打算使用它。如果你不想那样做
您可以将调用与patch
语句一起使用,将调用移至方法内的with
。
class TestFoo(unittest.TestCase):
def test_bar(self):
with patch('Foo.prompt', return_value=24):
f = Foo()
a = f.bar()
assert a == 24