Unit Testing JWT token exipiration: Django REST
Question: How do I test the case of attempting to refresh an expired token? Or the case
of trying to exceed `JWT_REFRESH_EXPIRATION_DELTA`?

I'm looking for the most pythonic/djangotacular way to unit test a token
refresh endpoint. AFAICT, my endpoint is working fine-it's refreshing the
token, and when I test it via python REPL, it does what I expect. But since
this is a documented bug I'm fixing, I'd like to end up with the fix under my
test harness. Testing the positive case is easy, but I'm unsure of how to
proceed from here. I don't want to do some delay loop or something like that,
since that would undermine the whole unit test ideology of running quickly and
in isolation...

my tests are currently using the `response = self.client.post(...)` style.


Answer: I can think of two ways to do what you want, and both involve using
[mocks](https://docs.python.org/3/library/unittest.mock.html). You must learn
to use mocks if you want to do serious isolated unit testing. ;)

First, mock the [`validate`](https://github.com/GetBlimp/django-rest-
framework-jwt/blob/master/rest_framework_jwt/serializers.py#L141) method of
the `RefreshJSONWebTokenSerializer` to raise `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
    

A second option is a bit more involved and would imply playing with the
current datetime:

    
    
    import datetime
    
    # http://stackoverflow.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)
    

I prefer the first option since it's easier.

