как включить токен csrf при тестировании конечной точки POST в django?

Я учусь, как сделать конечную точку api, и я пытаюсь написать тест, чтобы увидеть, возвращает ли запрос post код состояния 200. Я планирую написать больше тестов, чтобы увидеть, возвращает ли конечная точка все ожидаемые результаты. Я продолжаю получать код состояния 403, и я думаю, что это потому, что мне нужно включить токен csrf в данные post. Что такое хороший способ проверить конечную точку POST в django?

мой тест:

from django.test import TestCase
from app import settings
import requests

class ProjectEndpoint(TestCase):
   def post_endpoint(self):
      data = {'hello':'23'}
      post_project = requests.post(settings.BASE_URL+'/api/project', params=data)
      self.assertEqual(post_endpoint.status_code, 200)

этот тест продолжает терпеть неудачу с 403 != 200

Я думаю, это потому, что представление защищено от атак csrf, но я действительно не уверен. Ценю любое понимание, что кто-то.

1 ответов


фактически, django не применяет (по умолчанию) проверку csrf с помощью тестов, согласно https://docs.djangoproject.com/en/dev/ref/contrib/csrf/#testing:

CsrfViewMiddleware обычно будет большим препятствием для тестирования представления функции, из-за необходимости CSRF токен, который должен быть отправлен с каждый запрос POST. По этой причине HTTP-клиент Django для тестов был изменен, чтобы установить флаг для запросов, который расслабляет middleware и csrf_protect декоратор, чтобы они больше не отклоняет запросы. Во всех других отношениях (например, отправка cookies и т. д.), они ведут себя одинаково.

Если по какой-то причине вы хотите, чтобы тестовый клиент выполнял проверки CSRF, можно создать экземпляр тестового клиента, который применяет CSRF чеки:

от Джанго.тестовый клиент импорта

csrf_client = Client (enforce_csrf_checks=True)

однако это требует, чтобы вы использовали клиент Django против запросов; насколько я знаю, Django не издевается/instrument/etc. запросы... таким образом, вы на самом деле попадаете на реальный сервер, когда запускаете этот модульный тест.

также обратите внимание, что вы должны назвать свои тестовые функции чем-то, что начинается с test_

Итак, что-то вроде этого (при запуске через django manage.py тест .ProjectEndpoint)

def test_post_endpoint(self):
   data = {'hello':'23'}
   c = Client() #above, from django.test import TestCase,Client
   #optional, but may be necessary for your configuration: c.login("username","password")
   response = c.post('/api/project',params=data)
   self.assertEqual(response.status_code, 200)