Невозможно высмеять urllib2.urlopen с помощью pockon mock.patch

Ниже приведен фрагмент кода моего модуля api.py

# -*- coding: utf-8 -*- from urllib2 import urlopen from urllib2 import Request class API: def call_api(self, url, post_data=None, header=None): is_post_request = True if (post_data and header) else False response = None try: if is_post_request: url = Request(url = url, data = post_data, headers = header) # Calling api api_response = urlopen(url) response = api_response.read() except Exception as err: response = err return response 

Я пытаюсь urllib2.urlopen в unittest выше модуля. Я написал

 # -*- coding: utf-8 -*- # test_api.py from unittest import TestCase import mock from api import API class TestAPI(TestCase): @mock.patch('urllib2.Request') @mock.patch('urllib2.urlopen') def test_call_api(self, urlopen, Request): urlopen.read.return_value = 'mocked' Request.get_host.return_value = 'google.com' Request.type.return_value = 'https' Request.data = {} _api = API() assert _api.call_api('https://google.com') == 'mocked' 

После запуска unittest я получаю исключение

 <urlopen error unknown url type: <MagicMock name='Request().get_type()' id='159846220'>> 

Что мне не хватает? Пожалуйста, помогите мне.

One Solution collect form web for “Невозможно высмеять urllib2.urlopen с помощью pockon mock.patch”

Вы исправляете неправильные вещи: посмотрите, где патч .

В api.py по

 from urllib2 import urlopen from urllib2 import Request 

вы создаете локальную ссылку на urlopen и Request в вашем файле. От mock.patch('urllib2.urlopen') вы исправляете исходную ссылку и оставляете api.py одним нетронутым.

Итак, замените свои патчи на

 @mock.patch('api.Request') @mock.patch('api.urlopen') 

должен исправить вашу проблему …. но этого недостаточно.

В вашем тестовом примере api.Request не используется, но urllib2.urlopen() создает Request с использованием исправленной версии: вот почему Request().get_type() – это MagicMock .

Для полного исправления вы должны полностью изменить свой тест. Сначала код:

 @mock.patch('api.urlopen', autospec=True) def test_call_api(self, urlopen): urlopen.return_value.read.return_value = 'mocked' _api = API() self.assertEqual(_api.call_api('https://google.com'), 'mocked') urlopen.assert_called_with('https://google.com') 

Теперь уточнение … В вашем тесте вы не вызываете Request() потому что вы передаете только первый параметр, поэтому я удалил бесполезный патч. Кроме того, вы исправляете функцию urlopen а не объект urlopen , это означает, что метод read() который вы хотите насмехаться, является методом возврата объекта по urlopen() .

Наконец, я добавляю чек на вызов urlopen и autospec=True который всегда является хорошей практикой.

  • получение важных данных с веб-страницы с использованием python
  • Как ускорить работу urllib2 на Python при выполнении нескольких запросов
  • Обычная аутентификация с использованием urllib2 с python с JIRA REST api
  • Необходимо установить urllib2 для Python 3.5.1
  • Unescape Python Strings из HTTP
  • Хороший способ получить кодировку / кодировку ответа HTTP в Python
  • Есть ли библиотека для urllib2 для python, которую мы можем скачать?
  • add_header ожидает 3 аргумента вместо простого ключа / значения
  •  
    Interesting Posts for Van-Lav
    Python - лучший язык программирования в мире.