【问题标题】:Python unittest mock running program twicePython unittest模拟运行程序两次
【发布时间】:2019-11-14 00:01:54
【问题描述】:

试图更多地理解 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

另外,我怎样才能让它只运行一次代码,模拟值为“新测试”?

【问题讨论】:

  • 我将它作为 python test.py.. 运行,它确实给出了这些结果

标签: python python-unittest python-unittest.mock


【解决方案1】:

这是因为脚本首先作为模块 __main__ 加载,但您使用 test.testing 调用 patch,因此 patch 将再次导入 test.py 作为 test 模块。由于在打印"Setting up" 之前调用了patch,因此test 模块的加载以及__main__ 模块和test 模块对"Hello" 的打印将在@ 之前完成987654333@ 由__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

【讨论】:

  • 这很有意义。没有意识到补丁正在再次导入模块。非常感谢您的解释!
  • 强烈劝阻导入具有两个不同名称的同一个模块,并可能导致大量奇怪的错误。事实上,代码被导入两次,全局变量存在于两个不同的名称空间中,可能具有两个不同的值。只有当您使用不同的名称导入模块时,patch 才会再次导入该模块。换句话说,如果您以__main__ 执行脚本,那么您不应该修补"test.testing",而是应该模拟"__main__.testing"
猜你喜欢
  • 1970-01-01
  • 2021-04-12
  • 1970-01-01
  • 2018-03-12
  • 2020-11-26
  • 2022-01-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多