python unittest模拟/修补

时间:2018-09-24 21:21:33

标签: python mocking

不想手动测试我的代码,我试图编写一个模拟/修补我的依赖项的测试(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”,我认为这是装饰器所应用的函数,它使用两个参数来调用……但是……为什么呢?难道不是问题的本质吗?这样只能修补两个偶数的函数=)

1 个答案:

答案 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