Тестирование блока колбы: получение места перенаправления ответа

У меня есть веб-приложение, основанное на Flask, которое иногда создает новые документы с новыми случайными ключами при отправке в их родительский документ определенным образом. Новый ключ попадает в родительскую структуру данных, обновленный родитель временно сохраняется в сеансе и при успешном сохранении дочернего документа сохраненный родитель вытягивается из сеанса и сохраняется рядом с ним, чтобы связать их вместе. Это делается для определенных видов отношений, где требуется иметь встроенный порядок между ключами, поэтому ключи хранятся как список родительского элемента.

Теперь проблема возникает, когда я хочу unit test с помощью Werkzeug при условии, что unit test клиент. Выполнение

 ret = self.test_client.post(
    request_path,
    data=data,
    follow_redirects=True
)

в объекте тестового случая будет успешно перенаправляться на дочерний документ с новым ключом, но я не знаю, где взять этот новый ключ внутри модульных тестов. Я не могу найти атрибут поверх возвращаемого значения, которое указывало бы, куда оно было перенаправлено. dir(ret) дает мне

 ['__call__', '__class__', '__delattr__', '__dict__', '__doc__', '__enter__', '__exit__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_ensure_sequence', '_get_mimetype_params', '_on_close', '_status', '_status_code', 'accept_ranges', 'add_etag', 'age', 'allow', 'autocorrect_location_header', 'automatically_set_content_length', 'cache_control', 'calculate_content_length', 'call_on_close', 'charset', 'close', 'content_encoding', 'content_language', 'content_length', 'content_location', 'content_md5', 'content_range', 'content_type', 'data', 'date', 'default_mimetype', 'default_status', 'delete_cookie', 'direct_passthrough', 'expires', 'force_type', 'freeze', 'from_app', 'get_app_iter', 'get_data', 'get_etag', 'get_wsgi_headers', 'get_wsgi_response', 'headers', 'implicit_sequence_conversion', 'is_sequence', 'is_streamed', 'iter_encoded', 'last_modified', 'location', 'make_conditional', 'make_sequence', 'mimetype', 'mimetype_params', 'response', 'retry_after', 'set_cookie', 'set_data', 'set_etag', 'status', 'status_code', 'stream', 'vary', 'www_authenticate']

Из них headers и location выглядят многообещающими - однако местоположение не установлено, а заголовки также не содержат его.

Как я могу получить перенаправленное местоположение из ответа? Действительно ли я должен разбирать дочерний ключ из тела ответа? Разве нет лучшего способа?

Ответ 1

Следуя собственному ответу, в зависимости от вашего личного предпочтения стиля unit test, поэтому не стесняйтесь игнорировать, вы можете предпочесть что-то вроде следующего предложения, чтобы упростить и улучшить ясность и читаемость unit test:

response = self.test_client.post(
    request_path,
    data=data,
    follow_redirects=False
)
expectedPath = '/'
self.assertEqual(response.status_code, 302)
self.assertEqual(urlparse(response.location).path, expectedPath)

Ответ 2

@bwbrowning предоставил правильную подсказку - сделав сообщение с follow_redirects=False, возвращаемое значение имеет набор атрибутов location - это полный путь запроса, включая параметры.

edit: подсказка - при выполнении test_client.get(..) есть небольшой заголовок - параметр пути должен быть относительным путем, а ret.location возвращает полный путь. так что я сделал

child_path_with_parameters = rv.location.split('http://localhost')[1]
child_path = child_path_with_parameters.split('?')[0]
ret = self.test_client.get(child_path_with_parameters)

(путь child_path используется позже, чтобы отправить его дочернему элементу)