![](/img/trans.png)
[英]Testing authentication in Django Rest Framework Views — Cannot authenticate when testing
[英]When testing Django REST Framework, why can't I get APIClient.credentials() to authenticate using a token?
我正在針對基本的 API 編寫功能(不是單元)測試,如下所示:
from decouple import config
from rest_framework.test import APIClient, APITestCase
class ObjectAPIResponseTest(APITestCase):
base_url = 'http://localhost:8000/api/objects/'
token = config('LOCAL_API_TOKEN') # token stored in local .env file
authenticated_client = APIClient()
def setUp(self):
self.authenticated_client.credentials(HTTP_AUTHORIZATION='Token ' + self.token)
def test_list_object_reaches_api(self):
real_response = self.authenticated_client.get(self.base_url)
self.assertEqual(real_response.status_code, 200)
self.assertEqual(real_response.headers['content-type'], 'application/json')
測試失敗: AssertionError: 401 != 200
After successfully testing the request with curl, I decided to try to load up requests
with the Authorization
header instead of using Django REST Framework's APIClient
:
import requests
from decouple import config
from rest_framework.test import APIClient, APITestCase
class ObjectAPIResponseTest(APITestCase):
base_url = 'http://localhost:8000/api/objects/'
token = config('LOCAL_API_TOKEN') # token stored in local .env file
authentication_header = {
'Authorization': 'Token ' + token
}
def test_list_object_reaches_api(self):
real_response = requests.get(self.base_url, headers=self.authentication_header)
self.assertEqual(real_response.status_code, 200)
self.assertEqual(real_response.headers['content-type'], 'application/json')
這通過了,這讓我想知道我是否以某種方式錯誤地使用APIClient.credentials()
,盡管我所做的似乎基本上與文檔一致。
任何想法我做錯了什么?
更新
受 Hafnernuss 評論的啟發,我想看看APIClient
請求的行為如何,因此我檢查了APIClient
請求和requests
請求的響應。
看起來APIClient
實際上並沒有命中在我的開發服務器上運行的 API 端點,盡管我明確要求它的 URL。 如果我刪除需要對請求進行身份驗證的權限並通過 APIClient 發送請求:
client_response = self.authenticated_client.get(self.base_url)
print(client_response.data)
我得到這個response.data
:
[]
不過,我知道我的本地數據庫中至少有一個 object 可以通過該端點訪問。 如果我在測試的上下文中創建一個新的 object 並運行請求,我會得到 object 返回:
[OrderedDict([('id', 3), ('property', 'foo')])]
所以我認為我對APIClient
的幕后情況有一個根本的誤解。 是否以某種方式 mocking 向我的本地開發服務器的 URL 發出請求並從從測試運行者的數據庫中提取的人為端點請求?
這是繞過 API 身份驗證的替代解決方案:
事實上,為了禁用任何類型的 API 身份驗證(令牌、基本等),您只需在test_method()
之上使用以下裝飾器:
from unittest.mock import patch
from <Respetive-App>.<Respective-Views> import <Respective-View>
@patch.object(<Respective-View>, "permission_classes", [])
def test_post_rate(self, api_client):
payload = dict(content_id=self.content.id, score=5)
response = api_client.post(
"/api/endpoint/",
payload,
)
assert response.status_code == 201
將用戶的主鍵添加到此
base_url = 'http://localhost:8000/api/objects/' + f'{user.pk}/'
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.