【问题标题】:Patch not mocking a module补丁不模拟模块
【发布时间】:2017-03-21 19:36:10
【问题描述】:

我正在尝试模拟 subprocess.Popen。但是,当我运行以下代码时,模拟完全被忽略了,我不知道为什么

测试代码:

def test_bring_connection_up(self):
    # All settings should either overload the update or the run method
    mock_popen = MagicMock()
    mock_popen.return_value = {'communicate': (lambda: 'hello','world')}
    with patch('subprocess.Popen', mock_popen):
        self.assertEqual(network_manager.bring_connection_up("test"), "Error: Unknown connection: test.\n")

模块代码:

from subprocess import Popen, PIPE
# ........
def list_connections():
    process = Popen(["nmcli", "-t", "-fields", "NAME,TYPE", "con", "list"], stdout=PIPE, stderr=PIPE)
    stdout, stderr = process.communicate() # <--- Here's the failure
    return stdout

【问题讨论】:

  • 如果您将导入从from subprocess import Popen 更改为import subprocess,然后使用subprocess.Popen 代替Popen,该怎么办?
  • 我得到和上面一样的结果

标签: python unit-testing mocking


【解决方案1】:

您没有在正确的位置进行修补。您在定义 Popen 的位置打补丁:

with patch('subprocess.Popen', mock_popen):

您需要修补 Popen 的导入位置,即在您编写此行的“模块代码”中:

from subprocess import Popen, PIPE

也就是说,它应该看起来像:

with patch('myapp.mymodule.Popen', mock_popen):

如需快速指南,请阅读文档中的部分:Where to patch

【讨论】:

  • 等等.. 但是我该怎么做呢?该模块将有自己的导入,对吗?如果这仅用于测试,我如何告诉它有不同的导入?我应该传递变量告诉模块它处于测试模式并导入不同的信息吗?
  • 不,您不会出于测试目的而修改库代码。您修改测试代码以修补库代码。请阅读我链接的指南。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-11-26
  • 1970-01-01
  • 2020-10-16
相关资源
最近更新 更多