python - 打补丁时模块级代码运行两次

标签 python mocking python-mock patch

考虑以下简单代码:

test_code.py

def f():
    return 'unpatched'

import patch_stuff

patch_stuff.patch_it_up()
print f()

patch_stuff.py

from mock import patch

def patch_it_up():
    p = patch('test_code.f')
    m = p.start()
    m.return_value = 'patched'

我希望运行python test_code.py的输出为

patched

但是输出是:

unpatched
patched

怎么会?

最佳答案

您的代码中有两个问题。首先,test_code.py 文件被调用两次 - 第一次是当您调用它时,然后是当 mock 出于创建补丁的目的导入它时再次调用它。所以你应该按如下方式更改它:

def f():
    return 'unpatched'

import patch_stuff

if __name__ == "__main__":
    patch_stuff.patch_it_up()
    print f()

这将仅打印'unpatched'字符串。这就导致了第二件事:the documentation表明这不是修补程序的工作方式。当您调用 start 方法时,它会返回要使用的修补对象。因此通过以下修改可以达到预期的输出:

patch_stuff.py

from mock import patch

def patch_it_up():
    p = patch('test_code.f')
    m = p.start()
    m.return_value = 'patched'
    return m

test_code.py

def f():
    return 'unpatched'

import patch_stuff

if __name__ == "__main__":
    m = patch_stuff.patch_it_up()
    print m()

这将打印预期的'patched'字符串。

<小时/>

这使得这个场景不太实用,但是文档中的所有示例仅显示了修改当前上下文中导入的模块的可能性。例如,这也可以:

from mock import patch

def patch_it_up():
    import test_code
    p = patch('test_code.f')
    m = p.start()
    m.return_value = 'patched'
    print "inside patch_it_up:", test_code.f()

关于python - 打补丁时模块级代码运行两次,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26324578/

相关文章:

python - 如何在 Python 中模拟 redis 客户端?

使用导入模块进行 python 测试

python - Scrapy LinkExtractor - 限制每个 URL 抓取的页面数量

Python/Jinja2 - 使用 HTML 语法(Django)通过 python 生成的渲染列表出现问题

unit-testing - MOQ 和 AutoFixture 之间有什么区别?

python - Pytest:使用 python 线程在程序中模拟/修补 sys.stdin

python - 如何在 Python 2.7 中以 dd 格式获取今天的日期

Python线程运行()阻塞

unit-testing - 单元测试具有 ORM 交互的 Go 函数

python - 为迭代定制 unittest.mock.mock_open