修补时模块级代码运行两次

时间:2014-10-12 11:19:10

标签: 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

怎么来?

1 个答案:

答案 0 :(得分:1)

您的代码中存在两个问题。首先,调用 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()