Подпроцесс mocking. Открывается в зависимости от стиля импорта

При попытке смоделировать 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

Затем «выход» возвращается в тесте.

Любой желающий пролить некоторый свет на то, почему, я бы предпочел, чтобы импорт подпроцесса выполнялся из Popen, Pipe в обоих модулях, но я просто не могу заставить это посмеяться.

Ответы на вопрос(1)

Ваш ответ на вопрос