Подпроцесс издевательства. Открыть - PullRequest
0 голосов
/ 09 июня 2018

У меня есть модуль utils.py, у которого есть этот метод run_cmd ()

def run_cmd(cmd):
    pipe = subprocess.Popen(cmd,
                            shell=True,
                            stdout=subprocess.PIPE,
                            stderr=subprocess.PIPE)
    print(pipe.communicate())
    print(pipe.returncode)
    stdout, stderr = [stream.strip() for stream in pipe.communicate()]
    output = ' - STDOUT: "%s"' % stdout if len(stdout) > 0 else ''
    error = ' - STDERR: "%s"' % stdout if len(stderr) > 0 else ''
    logger.debug("Running [{command}] returns: [{rc}]{output}{error}".format(
                 command=cmd,
                 rc=pipe.returncode,
                 output=output,
                 error=error))

    return pipe.returncode, stdout, stderr

Я написал модульный тест, используя макет и эту ссылку stackoverflow в качестве ссылки

  @patch('subprocess.Popen')
  @patch('utils.logger.debug')
  def test_run_cmd(self, mock_popen, mock_log):
    cmd = 'mock_command'
    mocked_pipe = Mock()
    attrs = {'communicate.return_value': ('output', 'error'), 'returncode': 0}
    mocked_pipe.configure_mock(**attrs)
    mock_popen.return_value = mocked_pipe
    log_calls = [call('Running [mock_command] returns: [0]outputerror')]
    utils.run_cmd(cmd)
    mock_popen.assert_called_once_with(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    mock_log.assert_has_calls(log_calls)

Я получил это как вывод, когда я запускаю тест на нос

        stdout, stderr = [stream.strip() for stream in pipe.communicate()]
ValueError: need more than 0 values to unpack
-------------------- >> begin captured stdout << ---------------------
<MagicMock name='Popen().communicate()' id='140197276165008'>
<MagicMock name='Popen().returncode' id='140197276242512'>

--------------------- >> end captured stdout << ----------------------
FAILED (errors=1)

Почему pipe.communicate () не печатает ('output', 'error') или pipe.returncodeне печатать 0, но их ложные методы?Где это пошло не так?Как я мог решить это?

1 Ответ

0 голосов
/ 09 июня 2018

Ах, у вас уже есть ответ на ваш вопрос.Присмотритесь, и вы поймете, почему.Вы должны издеваться, как вы сделали для logger.Вы забыли упомянуть utils при создании макетируемого объекта.

@patch('utils.subprocess.Popen')

Теперь, насмехаясь над вложенной функцией с несколькими значениями, я думаю, вы должны взглянуть на side_effects и здесь.

Я не тестировал приведенный ниже код, но надеюсь, что он сработает или, по крайней мере, даст вам какое-то преимущество.

mocked_open.return_value.communicate.return_value = ('output', 'error')
mocked_open.return_value.returncode = 0

Надеюсь, это поможет!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...