【问题标题】:mocking subprocess.Popen dependant on import style模拟 subprocess.Popen 依赖于导入样式
【发布时间】:2015-06-25 12:49:37
【问题描述】:

当尝试模拟 Popen 时,如果子进程的导入在单元测试代码和主模块代码中都匹配,我只能让它成功。

给定以下模块 listdir.py:

from subprocess import Popen, PIPE

def listdir(dir):
    cmd = ['ls', dir]
    pc = Popen(cmd, stdout=PIPE, stderr=PIPE)
    out, err = pc.communicate()
    if pc.returncode != 0:
        raise Exception
    return out

以及下面的单元测试代码test_listdir.py

import subprocess
import listdir
import mock

@mock.patch.object(subprocess, 'Popen', autospec=True)
def test_listdir(mock_popen):
    mock_popen.return_value.returncode = 0
    mock_popen.return_value.communicate.return_value = ("output", "Error")
    listdir.listdir("/fake_dir")

由于某些原因,Popen 没有被模拟,因为两个 python 模块之间的导入样式不同,并且运行测试总是引发异常。

如果我更改 listdir.py 以导入所有子进程,例如

import subprocess

def listdir(dir):
    cmd = ['ls', dir]
    pc = subprocess.Popen(cmd, stdout=subprocess.PIPE, 
                          stderr=subprocess.PIPE)
    out, err = pc.communicate()
    if pc.returncode != 0:
        raise ListingErrorException
    return out

然后在测试中返回“输出”。

任何人都想弄清楚为什么,我的偏好是 from subprocess import Popen, Pipe in 这两个模块,但我就是无法模拟。

【问题讨论】:

    标签: python unit-testing mocking subprocess popen


    【解决方案1】:

    您需要在 listdir 中修补 Popen 的副本,而不是您刚刚导入的那个。所以,不要尝试@mock.patch.object(subprocess, 'Popen', autospec=True),而是尝试@mock.patch.object(listdir, 'Popen', autospec=True)

    有关更多信息,请参阅此文档:http://www.voidspace.org.uk/python/mock/patch.html#where-to-patch

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-05-15
      • 2021-05-22
      • 1970-01-01
      • 2018-11-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多