Насмешливый urllib2.urlopen(). Read() для разных ответов

Я пытаюсь смоделировать библиотеку urllib2.urlopen таким образом, чтобы получить разные ответы для разных URL-адресов, которые я передаю в функцию.

То, как я делаю это в моем тестовом файле, выглядит следующим образом

@patch(othermodule.urllib2.urlopen)
def mytest(self, mock_of_urllib2_urllopen):
    a = Mock()
    a.read.side_effect = ["response1", "response2"]
    mock_of_urllib2_urlopen.return_value = a
    othermodule.function_to_be_tested()   #this is the function which uses urllib2.urlopen.read

Я ожидаю, что othermodule.function_to_be_tested получит значение "response1" при первом вызове и "response2" при втором вызове, что и будет делать side_effect

но другой модуль.function_to_be_tested() получает

<MagicMock name='urlopen().read()' id='216621051472'>

а не фактический ответ. Пожалуйста, предложите, где я иду не так или более простой способ сделать это.

1 ответ

Решение

Аргумент к patch Должно быть описание местоположения объекта, а не самого объекта. Таким образом, ваша проблема выглядит так, как будто вам просто нужно привести ваш аргумент в соответствие patch,

Просто для полноты, но вот полностью рабочий пример. Во-первых, наш тестируемый модуль:

# mod_a.py
import urllib2

def myfunc():
    opened_url = urllib2.urlopen()
    return opened_url.read()

Теперь настройте наш тест:

# test.py
from mock import patch, Mock
import mod_a

@patch('mod_a.urllib2.urlopen')
def mytest(mock_urlopen):
    a = Mock()
    a.read.side_effect = ['resp1', 'resp2']
    mock_urlopen.return_value = a
    res = mod_a.myfunc()
    print res
    assert res == 'resp1'

    res = mod_a.myfunc()
    print res
    assert res == 'resp2'

mytest()

Запуск теста из оболочки:

$ python test.py
resp1
resp2

Изменить: Ой, изначально включены оригинальные ошибки. (Была проверка, чтобы проверить, как это было сломано.) Код должен быть исправлен сейчас.

Другие вопросы по тегам