2016-04-08 3 views
2

У меня есть метод под тестом, который выглядит следующим образом:Выполнить метод экземпляра с определенным возвращаемым значением?

def execute_update(self): 
    """Execute an update.""" 
    p = subprocess.Popen(['command'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT) 

    try: 
     stdout, stderr = p.communicate() 

     if p.returncode == 0: 
      # successful update, notify 
      self.logger.info("Successfully updated.") 
     else: 
      # failed update, notify 
      self.logger.error("Unable to update (code {returncode}):\n{output}".format(
       returncode=p.returncode, output=stdout)) 

    except KeyboardInterrupt as e: 
     # terminate the process 
     p.terminate() 
     raise e 

Я пытаюсь проверить его вызов Popen и его вызов функций лесозаготовок в методе unittest.TestCase теста с mock:

@mock.patch.object(subprocess.Popen, 'communicate', autospec=True) 
@mock.patch('updateservice.subprocess.Popen', autospec=True) 
def test_fetch_metadata(self, mock_popen, mock_communicate): 
    """Test that we can fetch metadata correctly.""" 
    mock_communicate.return_value = ("OUT", "ERR") 
    mock_popen.returncode = 0 

    self.reference.execute_update() 

    # other asserts 

последняя строка завершается с:

stdout, stderr = p.communicate() 
ValueError: need more than 0 values to unpack 

Что я делаю неправильно? У меня есть следующие требования:

  1. Протестировано, что конструктор subprocess.Popen был вызван с правильными значениями.
  2. Проверьте, что вызовы протоколирования работают с кодом вывода и возврата из процесса.

номер два достаточно легко, я просто нагнетание MagicMock как объект регистратора, но я "возникают проблемы с номером один.

+0

Попробуйте установить значение 'return_value' в строке' @ mock.patch.object'. – kindall

+0

Пробовал, что, такая же ошибка. –

+0

, как сказано в ошибке, вы перехватываете два значения в возврате ... из-за этого ваше значение return_value должно быть кортежем, например. (0,0) – Aquiles

ответ

2

Я думаю, что основная проблема исходит от вашего объекта патч здесь :

@mock.patch.object(subprocess.Popen, 'communicate', autospec=True) 

как ни странно, похоже, типа издеваться, который создается является:

<class 'unittest.mock.NonCallableMagicMock'> 

Это первый раз Я наткнулся на NonCallableMagicMock типа раньше, но, глядя на минимальной информации, которую я нашел на этом, документы указать this:

та часть, которая поднимает флаг для меня здесь:

за исключением return_value и side_effect, которые не имеют значения , что означает недопустимый макет.

Для определения того, что именно это означает, потребуется дополнительное расследование. Принимая, что к рассмотрению, и, возможно, вы уже пробовали это уже, следующее изменение ваших UnitTest урожайности успешных результатов насмешливо:

@mock.patch('server.upd.subprocess.Popen', autospec=True) 
def test_fetch_metadata(self, mock_popen): 
    """Test that we can fetch metadata correctly.""" 

    mock_popen.return_value = Mock() 
    mock_popen_obj = mock_popen.return_value 

    mock_popen_obj.communicate.return_value = ("OUT", "ERR") 
    mock_popen_obj.returncode = 0 

    self.reference.execute_update() 

Итак, как вы можете видеть, мы в значительной степени создает наш фиктивный объект согласно mock_popen.return_value , Оттуда все остальное в значительной степени согласовано с тем, что вы делали.

Смежные вопросы