It seems unusual to me that you use the patch decorator over the run_script
function, since you don’t pass a mock argument there.
How about this:
from unittest import mock
import subprocess
def run_script(file_path):
process = subprocess.Popen(["myscript", -M, file_path], stdout=subprocess.PIPE)
output, err = process.communicate()
return process.returncode
@mock.patch("subprocess.Popen")
def test_run_script(self, mock_subproc_popen):
process_mock = mock.Mock()
attrs = {"communicate.return_value": ("output", "error")}
process_mock.configure_mock(**attrs)
mock_subproc_popen.return_value = process_mock
am.account_manager("path") # this calls run_script somewhere, is that right?
self.assertTrue(mock_subproc_popen.called)
Right now, your mocked subprocess.Popen seems to return a tuple, causeing process.communicate() to raise TypeError: 'tuple' object is not callable.
. Therefore it’s most important to get the return_value on mock_subproc_popen just right.