如何提交模拟网址?

时间:2018-03-12 09:28:20

标签: python django python-3.x

我遇到了问题,我无法通过请求来测试我的表单。

add_playlist = self.client.post(reverse('new-playlist'),
                                    data={'url': 'https://dailyiptvlist.com/dl/it-m3uplaylist-2018-03-11-1.m3u'})

我需要为'https://dailyiptvlist.com/dl/fr-m3uplaylist-2018-03-06.m3u'创建模拟响应,因此在不维护网址时测试添加频道是可以接受的。所以,我需要为这个url创建一个模拟响应。我无法想象如何做到这一点。请帮帮我。

1 个答案:

答案 0 :(得分:0)

我认为您可以尝试使用此库(responses参见https://github.com/getsentry/responses),允许您使用模拟响应测试任意请求方案。

想法很简单:

  • 您在某些词典中对所需的回复进行了硬编码
  • 你创建了某个url的模拟,所以真正的请求不会出现在web中的某个地方,而是使用模拟数据和提供的状态代码等你使用responses.add配置的内容并且它在@responses.activate
  • 的装饰方法

示例测试 - 测试我的方法reverse_geocoding(latitude, longitude)从Google Maps API获取的整个响应中提取所需的内容:

import json
import responses

from django.conf import settings
from django.test import TestCase

from utils.geocoding import reverse_geocoding, REVERSE_GEOCODING_URL


RESPONSE_GEOCODING_MOCK = {
    'results': [
        {
            'address_components': [
                {'long_name': '74', 'short_name': '74', 'types': ['street_number']},
                {'long_name': 'Mickiewicza', 'short_name': 'Mickiewicza', 'types': ['route']},
                {'long_name': 'Żoliborz', 'short_name': 'Żoliborz', 'types': ['political', 'sublocality', 'sublocality_level_1']},
                {'long_name': 'Warszawa', 'short_name': 'Warszawa', 'types': ['locality', 'political']},
                {'long_name': 'Warszawa', 'short_name': 'Warszawa', 'types': ['administrative_area_level_2', 'political']},
                {'long_name': 'mazowieckie', 'short_name': 'mazowieckie', 'types': ['administrative_area_level_1', 'political']},
                {'long_name': 'Poland', 'short_name': 'PL', 'types': ['country', 'political']}
            ],
            'formatted_address': 'Mickiewicza 74, Warszawa, Poland',
            'geometry': {'location': {'lat': 52.2790223, 'lng': 20.980648},
                         'location_type': 'ROOFTOP',
                         'viewport': {'northeast': {'lat': 52.2803712802915, 'lng': 20.9819969802915},
                                      'southwest': {'lat': 52.2776733197085, 'lng': 20.9792990197085}}
                         },
            'place_id': 'ChIJxXoMrOfLHkcRBAFsrjKGcMc',
            'types': ['street_address']
        }
    ],
    'status': 'OK'
}


class TestGoogleAPIGeocodingConsumer(TestCase):

    @responses.activate
    def test_geocoding(self):
        latitude, longitude = 52.27904, 20.980366
        responses.add(
            responses.GET,
            REVERSE_GEOCODING_URL.format(
                latitude=latitude,
                longitude=longitude,
                api_key=settings.GOOGLE_API_KEY
            ),
            body=json.dumps(RESPONSE_GEOCODING_MOCK),
            content_type="application/json")

        response = reverse_geocoding(latitude, longitude)
        self.assertEqual(response, {'address_city': 'Warszawa',
                                    'address_country': 'Poland',
                                    'address_number': '74',
                                    'address_street': 'Mickiewicza'})

经测试的参考方法:

import requests
REVERSE_GEOCODING_URL = "https://maps.googleapis.com/maps/api/geocode/json?latlng={latitude},{longitude}&key={api_key}"


def reverse_geocoding(latitude, longitude):

    url = REVERSE_GEOCODING_URL.format(
        latitude=latitude,
        longitude=longitude,
        api_key=settings.GOOGLE_API_KEY
    )
    response = requests.get(url)
    info = response.json()
    address = {}

    for component in info['results'][0]['address_components']:
        if 'street_number' in component.get('types'):
            address['address_number'] = component['long_name']
        if 'route' in component.get('types'):
            address['address_street'] = component['long_name']
        if 'locality' in component.get('types'):
            address['address_city'] = component['long_name']
        if 'country' in component.get('types'):
            address['address_country'] = component['long_name']

    return address