Python unittest mock 运行 程序两次

Python unittest mock running program twice

试图更多地了解 unittest.mock,但不确定为什么它 运行 两次调用该程序。为简单起见,请考虑文件 test.py:

中的以下代码
from unittest.mock import patch

class T():
    def __init__(self):
        self.setup()

    def setup(self):
        mock_testing = patch('test.testing').start()
        mock_testing.return_value = "new testing"

def testing():
    return "testing"

print("Hello")

t = T()

print("Setting up")

if testing() == "testing":
    print("old style")
elif testing() == "new testing":
    print("new style")

当我 运行 带有 python test.py 的脚本时,我得到:

Hello
Hello
Setting up
new style
Setting up
old style

为什么 运行 代码两次?即使它 运行 它两次,为什么 'hello' 被背靠背打印,应该像这样打印:

Hello
Setting up
new style
Hello
Setting up
old style

另外,我怎样才能让它只 运行 一次代码,模拟值为 'new testing'?

这是因为脚本首先作为模块 __main__ 加载,而您使用 test.testing 调用 patch,因此 patch 将导入 test.py 再次作为 test 模块。由于在打印 "Setting up" 之前调用了 patchtest 模块的加载以及 __main__ 模块和test 模块,将在 "Setting up"__main__ 模块打印之前完成。

如果您将 __name__ 添加到 print 的参数中,您将更容易看到发生了什么:

from unittest.mock import patch

class T():
    def __init__(self):
        self.setup()

    def setup(self):
        mock_testing = patch('test.testing').start()
        mock_testing.return_value = "new testing"

def testing():
    return "testing"

print(__name__, "Hello")

t = T()

print(__name__, "Setting up")

if testing() == "testing":
    print(__name__, "old style")
elif testing() == "new testing":
    print(__name__, "new style")

这输出:

__main__ Hello
test Hello
test Setting up
test new style
__main__ Setting up
__main__ old style

为了避免这种情况,应该给__main__.testing打补丁,这样修改后,上面的代码会输出:

__main__ Hello
__main__ Setting up
__main__ new style