У меня есть сложная проблема, с которой я не могу справиться. Я , в настоящее время пишу модульные тесты для пользовательского auth-backend django. В нашей системе у нас фактически есть два backend: один встроенный django backend и пользовательский бэкэнд, который отправляет запросы на Java-API , который возвращает информацию о пользователе в форме XML. Теперь я пишу блок , поэтому я не хочу отправлять запросы за пределами системы, например, , что я не пытаюсь протестировать Java API, поэтому мой вопрос: как я могу обойти это и высмеять побочные эффекты наиболее надежным способом.Чистое издевательствование удаленных серверов и API для Django Unittests
Функция Я проверяю что-то вроде этого, где настройки значения URL только базовый URL для сервера Java, который проверяет подлинность данных имя пользователя и пароль и возвращает XML, а стоимость услуг является лишь некоторые магия для создания запроса URL-адреса, его неважным для нас:
@staticmethod
def get_info_from_api_with_un_pw(username, password, service=12345):
url = settings.AUTHENTICATE_URL_VIA_PASSWORD
if AUTH_FIELD == "username":
params = {"nick": username, "password": password}
elif AUTH_FIELD == "email":
params = {"email": username, "password": password}
params["service"] = service
encoded_params = urlencode([(k, smart_str(v, "latin1")) for k, v in params.items()])
try:
# get the user's data from the api
xml = urlopen(url + encoded_params).read()
userinfo = dict((e.tag, smart_unicode(e.text, strings_only=True))
for e in ET.fromstring(xml).getchildren())
if "nil" in userinfo:
return userinfo
else:
return None
Таким образом, мы получаем XML, разобрать его в Словаре и если ключ ноль присутствует , то мы можем вернуть Dict и продолжать счастливым и аутентифицированы. Очевидно, что одно решение просто найти способ хоть как-то переопределить или monkeypatch логика в переменной XML, я нашел этот ответ:
How can one mock/stub python module like urllib
Я пытался реализовать что-то подобное, но детали там очень отрывочно, и я не мог заставить работать.
Я также захватил ответ XML и поместить его в локальном файл в папке теста с целью найти способ использовать это в качестве притворного ответа, который передается в параметр URL-адрес функции теста, что-то вроде этого будет переопределить URL:
@override_settings(AUTHENTICATE_URL_VIA_PASSWORD=(os.path.join(os.path.dirname(__file__), "{0}".format("response.xml"))))
def test_get_user_info_username(self):
self.backend = RemoteAuthBackend()
self.backend.get_info_from_api_with_un_pw("user", "pass")
Но также необходимо принимать во внимание URL здания логики, что функция определяет, (т.е. «URL + encoded_params»). Опять же, я мог бы переименовать , чтобы файл ответов был таким же, как и конкатенированный URL-адрес, но это становится меньше, чем хороший юнит-тест для этой функции и более «чит», вся информация о просто становится все более и более хрупкое все время с этими решениями, и его действительно просто арматура в любом случае, чего я тоже хочу избежать, если вообще возможно .
Я также задавался вопросом, может ли быть способ обслуживать xml на сервере разработки django, а затем указывать на него функцию? Это похоже на более здравое решение, но многие поисковые запросы не дали мне никаких подсказок, если бы такое было возможно или целесообразно, и даже тогда я не думаю, что это было бы испытание на запуск за пределами среды разработки.
Таким образом, в идеале, мне нужно, чтобы иметь возможность как-то издеваться «сервер», чтобы занять место в Java API, в вызове функции, или каким-то образом служить некоторый XML полезной нагрузки, что функция может открыть в качестве URL , или monkeypatch функция от самого теста, или ...
Есть ли в библиотеке макета соответствующие инструменты для выполнения таких задач?
http://www.voidspace.org.uk/python/mock
Итак, есть две точек на этот вопрос 1) Я хотел бы, чтобы решить мою конкретной проблемы в чистом виде, и что более важно 2) каковы лучших практики для чисто написания блок Джанго -tests, когда вы являетесь в зависимости от данных, куки-файлов и т. д. для аутентификации пользователей с удаленного API, который находится за пределами вашего домена?
В вашем случае вам нужно высмеять следующее: 'import models; self.mock ('models.urlopen') ', поскольку, кажется, вы импортировали его в свой файл модели' from urllib import urlopen'. – Pykler
Ах, это здорово, похоже, что такая насмешка - это всего лишь билет. Огромное спасибо! – osman