Подтвердить что ты не робот

Как издеваться над внешними серверами в модульных тестах Python?

У меня есть несколько модульных тестов, которые занимают много времени (минуты) из-за вызовов внешних служб (Twitter, Facebook, Klout и т.д.).

Я хотел бы кэшировать результаты этих сервисов и показывать их прозрачно, с минимальными изменениями в моих текущих тестах. Кэш-ключ зависит от URL, аргументов запроса, заголовков и т.д., Поэтому он довольно сложный.

Какой лучший способ сделать это?

4b9b3361

Ответ 1

Вы бы (должны) обычно использовали какой-то адаптер для подключения к этим внешним службам, модулям. Это ваши интерфейсы для внешнего мира и могут быть mock ed и поддельные ответы, созданные в зависимости от сценария.

Я экспериментировал с несколькими насмешливыми библиотеками и, наконец, нашел Mock, чтобы быть наиболее подходящим для меня.

Ответ 2

Вот код. Мы используем библиотеку запросов для вызова внешних API. Поэтому мы создаем контекстный процессор с объектом mock запросов.

Итак, если бы мы тестировали функцию get_data, это было бы тем, как мы будем обманывать запрос внешнему API:

import requests
import mock
import unittest


def get_data(url):
    resp = requests.get(url)
    return resp

class GetDataTest(unittest.TestCase):

    def test_get_data(self):
        with mock.patch.object(requests, 'get') as get_mock:
            get_mock.return_value = mock_response = mock.Mock()
            mock_response.status_code = 200
            mock_response.content = {'twitter_handle': '@twitter'}
            resp = get_data("http://this_address_does_not_exist.com")
            self.assertEqual(resp.status_code, 200)
            self.assertEqual(resp.content['twitter_handle'], '@twitter')

Ответ 3

Технически, если он использует внешние службы, это не unit test, а тест интеграции. Для unit test и ускорьте свой тестовый код, используя mock-объекты. Здесь вы можете найти информацию о mock-объектах python:
http://python-mock.sourceforge.net/