burlándose de subproceso.Popen dependiente del estilo de importación

Al intentar burlarse de Popen solo puedo lograr que tenga éxito si la importación de subprocesos coincide con el código de prueba de la unidad y el código del módulo principal.

Dado el siguiente listdir.py módulo:

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 

y siguiendo el código de prueba de la unidad 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") 

Por alguna razón, Popen no está siendo burlado, debido a que el estilo de importación es diferente entre los dos módulos de Python, y la ejecución de la prueba siempre genera una excepción.

Si cambio listdir.py para importar todas las subprocesas, por ejemplo

 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 

Luego se devuelve “output” en la prueba.

A cualquier persona le gustaría aclarar por qué, mi preferencia sería tener un subproceso para importar Popen, Pipe en ambos módulos, pero simplemente no puedo hacer que eso se burle.

Debe parchear la copia de Popen en listdir, no la que acaba de importar. Entonces, en lugar de @mock.patch.object(subprocess, 'Popen', autospec=True) , intente @mock.patch.object(listdir, 'Popen', autospec=True)

Consulte este documento para obtener más información: http://www.voidspace.org.uk/python/mock/patch.html#where-to-patch