Python mock, django и запросы

Итак, я только начал использовать макет с проектом Django. Я пытаюсь смоделировать часть представления, которое отправляет запрос к удаленному API, чтобы подтвердить, что запрос на подписку был подлинным (форма проверки в соответствии со спецификацией, над которой я работаю).

Что у меня похоже:

class SubscriptionView(View):
    def post(self, request, **kwargs):
        remote_url = request.POST.get('remote_url')
        if remote_url:
            response = requests.get(remote_url, params={'verify': 'hello'})

        if response.status_code != 200:
            return HttpResponse('Verification of request failed')

Теперь я хочу использовать mock для имитации вызова requests.get для изменения ответа, но я не могу понять, как это сделать для декоратора патчей. Я думал, вы делаете что-то вроде:

@patch(requests.get)
def test_response_verify(self):
    # make a call to the view using self.app.post (WebTest), 
    # requests.get makes a suitable fake response from the mock object

Как мне этого добиться?


person jvc26    schedule 17.04.2013    source источник
comment
Deadset на использовании mocks? Также есть django.test.client.RequestFactory — docs.djangoproject.com/en/1.5/topics/testing/advanced/   -  person David    schedule 18.04.2013
comment
Просто для будущих зрителей: автор вопроса хотел смоделировать внешний вызов API. Не вызов самого представления. Моки кажутся очень разумными в этой ситуации.   -  person aychedee    schedule 06.06.2014
comment
Согласно @aychedee, это действительно то, к чему я стремился с этим вопросом.   -  person jvc26    schedule 07.06.2014


Ответы (2)


Ты почти там. Вы просто немного неправильно его называете.

from mock import call, patch


@patch('my_app.views.requests')
def test_response_verify(self, mock_requests):
    # We setup the mock, this may look like magic but it works, return_value is
    # a special attribute on a mock, it is what is returned when it is called
    # So this is saying we want the return value of requests.get to have an
    # status code attribute of 200
    mock_requests.get.return_value.status_code = 200

    # Here we make the call to the view
    response = SubscriptionView().post(request, {'remote_url': 'some_url'})

    self.assertEqual(
        mock_requests.get.call_args_list,
        [call('some_url', params={'verify': 'hello'})]
    )

Вы также можете проверить, что ответ имеет правильный тип и правильное содержание.

person aychedee    schedule 17.04.2013

Все это описано в документации:

patch(target, new=DEFAULT, spec=None, create=False, spec_set=None, autospec=None, new_callable=None, **kwargs)

цель должна быть строкой в ​​форме «package.module.ClassName».

from mock import patch

# or @patch('requests.get')
@patch.object(requests, 'get')
def test_response_verify(self):
    # make a call to the view using self.app.post (WebTest), 
    # requests.get makes a suitable fake response from the mock object
person gatto    schedule 17.04.2013