twi*_*ity 5 python django functional-testing django-testing django-rest-framework
我正在针对基本 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')
Run Code Online (Sandbox Code Playgroud)
测试失败:AssertionError: 401 != 200
使用curl成功测试请求后,我决定尝试requests使用Authorization标头加载,而不是使用Django REST Framework的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')
Run Code Online (Sandbox Code Playgroud)
这通过了,这让我想知道我是否以某种方式使用APIClient.credentials()不正确,尽管我所做的似乎基本上符合文档。
有什么想法我做错了吗?
更新
受到 Hafnernuss 评论的启发,我想了解请求的行为方式,因此我检查了请求和请求APIClient的响应。APIClientrequests
尽管我明确地请求了其 URL,但它看起来APIClient实际上并没有命中在我的开发服务器上运行的 API 端点。如果我删除要求对请求进行身份验证的权限并通过 APIClient 发送请求:
client_response = self.authenticated_client.get(self.base_url)
print(client_response.data)
Run Code Online (Sandbox Code Playgroud)
我得到这个response.data:
[]
Run Code Online (Sandbox Code Playgroud)
不过,我知道我的本地数据库中至少有一个对象可以通过该端点访问。如果我在测试上下文中创建一个新对象并运行请求,我会返回该对象:
[OrderedDict([('id', 3), ('property', 'foo')])]
Run Code Online (Sandbox Code Playgroud)
所以我认为我对 的幕后情况有一个根本性的误解APIClient。它是否以某种方式模拟了对我的本地开发服务器 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
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3392 次 |
| 最近记录: |