单元测试 JWT 令牌过期:Django REST

Posted

技术标签:

【中文标题】单元测试 JWT 令牌过期:Django REST【英文标题】:Unit Testing JWT token exipiration: Django REST 【发布时间】:2015-05-12 07:23:57 【问题描述】:

如何测试尝试刷新过期令牌的情况?还是试图超过JWT_REFRESH_EXPIRATION_DELTA的情况?

我正在寻找最 Pythonic/djangotacular 的方式来对令牌刷新端点进行单元测试。 AFAICT,我的端点工作正常——它正在刷新令牌,当我通过 python REPL 测试它时,它符合我的预期。但由于这是我正在修复的记录错误,我想在我的测试工具下完成修复。测试阳性病例很容易,但我不确定如何从这里开始。我不想做一些延迟循环或类似的事情,因为这会破坏快速和孤立运行的整个单元测试思想......

我的测试目前使用response = self.client.post(...) 样式。

【问题讨论】:

【参考方案1】:

我可以想到两种方法来做你想做的事,都涉及使用mocks。如果你想做严肃的独立单元测试,你必须学会​​使用模拟。 ;)

首先,模拟RefreshJSONWebTokenSerializervalidate方法来提升serializers.ValidationError

from rest_framework import serializers
@mock.patch('rest_framework_jwt.RefreshJSONWebTokenSerializer.validate')
def test_token_expiry_refresh(self, validate_mock):
    validate_mock.side_effect = serializers.ValidationError('Refresh has expired.')
    response = self.client.post('/refresh-token-url/')
    self.assertEquals(response.status, 400)  # I believe it's this code what ValidationError should return

第二个选项涉及更多,意味着使用当前日期时间:

import datetime

# http://***.com/a/5437199/356729
class FakeDateTime(datetime):
    "A manipulable datetime replacement"
    def __new__(cls, *args, **kwargs):
        return datetime.__new__(datetime, *args, **kwargs)

@patch('rest_framework_jwt.RefreshJSONWebTokenSerializer.datetime', FakeDateTime)
def test_token_expiry_refresh(self):
    FakeDateTime.utcnow = classmethod(lambda cls: datetime.utcnow() + timedelta(0, 10))
    response = self.client.post('/refresh-token-url/')
    self.assertEquals(response.status, 400)

我更喜欢第一个选项,因为它更容易。

【讨论】:

如何定义 validate_mock 夹具?

以上是关于单元测试 JWT 令牌过期:Django REST的主要内容,如果未能解决你的问题,请参考以下文章

Django REST JWT 刷新

Django rest framework JWT ,删除 jwt 令牌

Django-Rest-Framework JWT 单元测试说“未提供身份验证”

如何在 django rest 框架中验证 jwt 身份验证中的令牌

Django Rest Framework 避免身份验证 JWT

Django Rest Framework JWT 身份验证测试