Python 在测试Django REST框架时,为什么';我是否获取APIClient.credentials()以使用令牌进行身份验证?
我正在编写一个针对基本API的功能(而不是单元)测试,如下所示: 来自解耦导入配置的Python 在测试Django REST框架时,为什么';我是否获取APIClient.credentials()以使用令牌进行身份验证?,python,django,django-rest-framework,functional-testing,Python,Django,Django Rest Framework,Functional Testing,我正在编写一个针对基本API的功能(而不是单元)测试,如下所示: 来自解耦导入配置的 从rest\u framework.test导入APIClient、APITESCASE 类ObjectAPIResponseTest(ApitTestCase): 基本url=http://localhost:8000/api/objects/' token=config('LOCAL_API_token')#存储在LOCAL.env文件中的令牌 已验证的_client=APIClient() def设置(自
从rest\u framework.test导入APIClient、APITESCASE
类ObjectAPIResponseTest(ApitTestCase):
基本url=http://localhost:8000/api/objects/'
token=config('LOCAL_API_token')#存储在LOCAL.env文件中的令牌
已验证的_client=APIClient()
def设置(自):
self.authenticated_client.credentials(HTTP_authentication='Token'+self.Token)
def测试列表对象到达api(自身):
real\u response=self.authenticated\u client.get(self.base\u url)
self.assertEqual(真实响应状态代码,200)
self.assertEqual(real_response.headers['content-type'],'application/json')
测试失败:AssertionError:401!=200
在使用curl成功测试请求之后,我决定尝试使用授权头加载请求
,而不是使用Django REST框架的APIClient
:
导入请求
从解耦导入配置
从rest\u framework.test导入APIClient、APITESCASE
类ObjectAPIResponseTest(ApitTestCase):
基本url=http://localhost:8000/api/objects/'
token=config('LOCAL_API_token')#存储在LOCAL.env文件中的令牌
身份验证\u头={
“授权”:“令牌”+令牌
}
def测试列表对象到达api(自身):
real\u response=requests.get(self.base\u url,headers=self.authentication\u header)
self.assertEqual(真实响应状态代码,200)
self.assertEqual(real_response.headers['content-type'],'application/json')
这就过去了,这让我怀疑我是否以某种方式错误地使用了APIClient.credentials()
,尽管我所做的基本上与此一致
知道我做错了什么吗
更新
受到Hafnernus评论的启发,我想看看APIClient
请求的行为,因此我检查了APIClient
请求和请求的响应
看起来,APIClient
实际上并没有命中在我的开发服务器上运行的API端点,尽管我对其URL进行了显式请求。如果我删除了要求对请求进行身份验证的权限,并通过ApicClient发送请求:
client\u response=self.authenticated\u client.get(self.base\u url)
打印(客户端响应.数据)
我得到的是响应。数据:
[]
不过,我知道本地数据库中至少有一个对象可以通过该端点访问。如果我在测试上下文中创建一个新对象并运行该请求,我将返回该对象:
[OrderedDict([('id', 3), ('property', 'foo')])]
因此,我想我对APIClient
的幕后运作有一个基本的误解。它是否以某种方式模拟了对本地开发服务器URL的请求,并从一个从测试运行者数据库中提取的人为端点进行请求?我不完全确定,但数据库可能会存储您随请求发送的令牌。如果您从env加载令牌,并且该令牌未存储在db中,那么API如何知道该令牌属于哪个用户?我不知道为什么你的第二次测试通过了,因为你应该有同样的问题。我用于授权的令牌与存储在我的本地开发服务器数据库中的令牌匹配,这就是我的本地开发服务器知道请求被授权的方式。不过,你的评论引发了一个想法,试图找出答案。关于你的更新。。。同样,不确定,但如何确保此条目确实存在于数据库中?在测试时,django设置了一个每次都被清除的专用测试数据库(这也意味着令牌不存在!)。在我的测试中,我在testclass的setUp函数中插入了我的行(如accounts等)。是的,随着我对Django测试运行程序的更多了解,现在我发现我实际上对如何APIClient
以及测试运行程序的内部在一般工作中的工作方式有一个基本的误解。APIClient
即使在命中一个活动端点时也会以这种方式运行,这是违反直觉的(至少对我来说),但在Django的测试运行程序中内置的测试隔离的更广泛的上下文中,这是有意义的。如果您正在针对持久数据库运行测试,那么您的测试将不再在受控环境中执行。这适用于所有内部测试。即使是mymodel.objects.all()
在测试时也不会返回您的行。