2015-09-07 3 views
2

Я пишу тесты для представлений django. Некоторые из представлений обрабатывают внешние HTTP-запросы. Во время выполнения тестов я не хочу выполнять эти HTTP-запросы. Так как во время тестов данные используются, это фиктивный, и эти HTTP-запросы не будут вести себя так, как ожидалось.Django: избегайте вызовов HTTP API во время тестирования из представлений django

Что может быть возможным для этого?

ответ

1

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

Вы можете прочитать хорошее сообщение в блоге о насмешливости в Python here.

Если вы находитесь на Python 3.3 или новее, библиотека mock включена в Python. Если нет, вы можете скачать его с PyPI.

Точные сведения о том, как издеваться над вашими звонками, будут зависеть от того, как выглядит ваш код вида.

+1

хорошая статья, которую вы поделили, это можно использовать для издевательства над определенной частью кода. Но не получить, как взгляд django можно протестировать в целом. – navyad

1

Вы можете переопределить настройки в своих тестах и ​​затем проверить эту настройку в своем представлении. Here - это документы для переопределения настроек.

from django.conf import settings 
if not settings.TEST_API: 
    # api call here 

Тогда ваш тест будет выглядеть примерно так

from django.test import TestCase, override_settings 

class LoginTestCase(TestCase): 

    @override_settings(TEST_API=True) 
    def test_api_func(self): 
     # Do test here 

Поскольку было бы довольно запутанна, чтобы иметь те повсюду, я бы рекомендовал создать подмешать, который будет выглядеть примерно так.

class SensitiveAPIMixin(object): 
    def api_request(self, url, *args, **kwargs): 
     from django.conf import settings 
     if not settings.TEST_API: 
      request = api_call(url) 
      # Do api request in here 
     return request 

Затем, через силу множественного наследования, ваши мнения, что вам нужно сделать запрос на этот апи позвонить вы могли бы сделать что-то похожее на это.

class View(generic.ListView, SensitiveAPIMixin): 
    def get(self, request, *args, **kwargs): 
     data = self.api_request('http://example.com/api1') 
+1

не кажется элегантное решение для подключения этого состояния путем из кода приложения, – navyad

+0

Вы правы, если вы делали это вручную везде. Но это то, где происходит наследование. Я бы, вероятно, создал пользовательский базовый вид или просто очень простой mixin и базовую функцию, которая просто заставляет api-вызов с заданным URL-адресом проверять эти параметры, а затем просто использовать эту функцию во всем приложении. Я могу показать вам, как это будет выглядеть, если хотите. – electrometro

0

Бен находится прямо на месте, но вот какой-то код psuedo-ish, который может помочь. Патч здесь предполагает, что вы используете requests, но при необходимости измените путь, чтобы издеваться над тем, что вам нужно.

from unittest import mock 
from django.test import TestCase 
from django.core.urlresolvers import reverse 

class MyTestCase(TestCase): 

    @mock.path('requests.post') # this is all you need to stop the API call 
    def test_my_view_that_posts_to_an_api(self): 
     response = self.client.get(reverse('my-view-name')) 

     self.assertEqual('my-value', response.data['my-key']) 
     # other assertions as necessary