#django #api #testing #mocking #pytest
Вопрос:
Я написал и API, который использует аутентификацию JWT.
Я протестировал api с помощью postman и смог получить файл cookie csrf и токен доступа после входа пользователя в систему, а затем я могу использовать эти токены для использования конечных точек API.
Для тестирования я использую pytest-django, который создает макет базы данных. Все работает, когда я тестирую регистрацию пользователя, вход в систему пользователя и когда я использую конечные точки GET. Для СООБЩЕНИЯ, которое я должен отправить в заголовках (как в Postman), токен csrf и access_token, проблема в том, что я не понимаю, как их отправить.
Например, в тесте GET я могу получить маркер доступа следующим образом
def test_get_signal():
form_data = {
"username": "testuser",
"email": "email@email.com",
"password": "mytestpassword",
}
CustomUser.objects.create_user(**form_data)
response = APIclient.post("/login/", form_data)
assert response.status_code == 200
response_content = json.loads(response.content)
token = response_content["access_token"]
APIclient.credentials(HTTP_AUTHORIZATION="Bearer " token)
response = APIclient.get(
path="/api/v1/signals/",
)
assert response.status_code == 200
но я не знаю, как отправить токен csrf в заголовке запроса post.
По этой причине (как и все работы в postman) Я реализовал агностический способ тестирования, для которого требуется живой сервер
@pytest.mark.skip_in_ci
@pytest.mark.skip(reason="This test needs localhost django server running")
def test_post_signal():
client = APIClient(enforce_csrf_checks=True)
form_data = {
"username": "testuser",
"email": "email@email.com",
"password": "mytestpassword",
}
user = CustomUser.objects.create_user(**form_data)
response = client.post("/login/", form_data)
csrf_token = client.cookies["csrftoken"].value
response_content = json.loads(response.content)
access_token = response_content["access_token"]
assert response.status_code == 200
user
url = "http://localhost:8000/api/v1/signals/"
payload = json.dumps(
{"data": [101, 1, 3, 3, 401, 3, 4, 1, 2, 10], "threshold": 3, "user": user.pk}
)
headers = {
"X-CSRFTOKEN": csrf_token,
"Authorization": "Bearer " access_token,
"Content-Type": "application/json",
"Cookie": "csrftoken=" csrf_token,
}
res = requests.request("POST", url, headers=headers, data=payload)
assert res.status_code == 201
content = json.loads(res.text)
signal_id = content["pk"]
url = "http://localhost:8000/api/v1/signals/" str(signal_id) "/"
res = requests.request("DELETE", url, headers=headers)
Этот тест записывает данные в живую базу данных.
Интересно, есть ли способ переписать тест с помощью pytest-django без использования живого сервера