Я думаю, что лучший подход состоит в том, чтобы смоделировать подмножество httplib.HTTPConnection
(вызовите получившийся класс mockcon
для конкретизации в следующем) и добавить обработчик, используя его, и создать подкласс HTTPHandler
(использовать в build_opener
- подкласс означает, что он может заменить HTTPHandler
, который build_opener
использует по умолчанию):
class MockHTTPHandler(urllib2.HTTPHandler):
def http_open(self, req):
return self.do_open(mockcon, req)
Класс mockcon должен предоставлять вызовы методов do_open
- несколько могут бытьпустышки (т.е. принимают и игнорируют произвольные аргументы и аргументы kwds и ничего не делают):
set_debuglevel
_set_tunnel
request
(может интересовать 2-й аргумент request
, поскольку он дает часть URL-адреса "селектор").
Метод __init__
для mockcon
получает часть URL-адреса хоста в качестве первого аргумента (то есть, сначала после self
, конечно) и должен игнорировать следующие kwds (используется для установки тайм-аута).
Метод get_response
mockcon
(без аргументов, кроме, конечно, self
) должен возвращать объект ответа http - то есть файлоподобный читаемый объект, который также имеет атрибуты .msg
,.status
, .reason
и метод get_full_url()
для возврата URL.
Вы можетеse фактический экземпляр httplib.HTTPResponse
для последней роли, но вы должны инициализировать его одним аргументом mock / dummy, который имеет аргумент makefile
(игнорирует его args и kwds и возвращает все, что угодно), и сразу после инициализации сбрасывает его.fp
аргументом должен быть rb
открытый файл, дающий в точности те байты, которые реальный HTTP-ответ получит на своем сокете.
Я думаю, что создание полноценного макета для всего вызова urllib2.urlopen
можетбыть проще, чем эта попытка повторно использовать большую часть функциональности urllib2
(и httplib
, которую он использует внутри), хотя, возможно, не так просто, как подход «локальный веб-сервер», который, как вам кажется, более эффективен.Но стоит рассмотреть все три подхода (макет, безусловно, будет самым легким / быстрым в работе, локальный веб-сервер медленнее ... и также потребует как-то изменить URL-адреса, добавив к ним префикс http://localhost:someport/
, конечно).