5

Die Abfrage zu meinem Endpunkt funktioniert gut (solange ich ein gültiges Token übergebe), es gibt die JSON-Darstellung meiner Antwortdaten zurück.Was ist der richtige Weg, tokenbasierte Authentifizierung mit APIRequestFactory zu testen?

Der Code im Dienst api, dass mein Endpunkt aufruft, ein Auth-Token im Header übergeben:

headers = {'content-type': 'application/json', 
      'Authorization': 'Token {}'.format(myToken)} 
url = 'http://localhost:8000/my_endpoint/' 
r = session.get(url=url, params=params, headers=headers) 

In views.py, habe ich eine Methode Dekorateur habe, die Versandart auf der Ansicht, Wraps (Viewset .ReadOnlyModelViewSet):

def login_required(f): 
    def check_login_and_call(request, *args, **kwargs): 
     authentication = request.META.get('HTTP_AUTHORIZATION', b'') 
     if isinstance(authentication, str): 
      authentication = authentication.encode(HTTP_HEADER_ENCODING) 
     key = authentication.split() 
     if not key or len(key) != 2: 
      raise PermissionDenied('Authentication failed.') 
     user, token = authenticate_credentials(key[1]) 
     return f(request, *args, **kwargs) 
    return check_login_and_call 

ich versuche, einen Test zu schreiben, um die Anforderung zu authentifizieren, um eine Token:

from rest_framework.authtoken.models import Token 
from rest_framework.test import APIRequestFactory 
from rest_framework.test import APITestCase 
from rest_framework.test import force_authenticate 

class EndpointViewTest(APITestCase): 
    def setUp(self): 
     self.factory = APIRequestFactory() 
     self.user = User.objects.create_user(
      username='[email protected]', email='[email protected]', password='top_secret') 
     self.token = Token.objects.create(user=self.user) 
     self.token.save() 

    def test_token_auth(self): 
     request = self.factory.get('/my_endpoint') 
     force_authenticate(request, token=self.token.key) 
     view = views.EndpointViewSet.as_view({'get': 'list'}) 
     response = view(request) 
     self.assertEqual(response.status_code, 200) 
     json_response = json.loads(response.render().content)['results'] 

Aus irgendeinem Grund kann ich nicht die Anforderung erhalten, das Token für diesen Test ordnungsgemäß zu übergeben. Die Verwendung von force_authenticate scheint den Header, den ich für die Überprüfung des Tokens verwende, nicht zu ändern. Die aktuelle Ausgabe verursacht "PermissionDenied: Authentifizierung fehlgeschlagen." weil das Token für die Anfrage nicht gesetzt ist.

Gibt es eine geeignete Möglichkeit, dies in der Anforderungsheader in meinem Test zu setzen oder um die Art und Weise, wie ich es benutze, neu zu gestalten?

Antwort

11

Ich fand einen Weg, um den Test zu bestehen, aber bitte posten, wenn Sie eine bessere Idee haben, wie Sie damit umgehen sollen.

Nach dem Ändern der oben genannten zwei Zeilen des Tests scheint es, basierend auf dem Token ordnungsgemäß zu authentifizieren.

2

Sorry für diesen alten Thread bis zu graben, aber wenn jemand APIClient() wird mit ihren Tests zu tun, können Sie wie folgt vorgehen:

from rest_framework.test import APITestCase 
from rest_framework.test import APIClient 
from rest_framework.authtoken.models import Token 
from django.contrib.auth.models import User 


class VehicleCreationTests(APITestCase): 

    def setUp(self): 
     self.client = APIClient() 
     self.user = User.objects.create_superuser('admin', '[email protected]', 'admin123') 
     self.token = Token.objects.create(user=self.user) 

    def testcase(self): 
     self.client.force_login(user=self.user) 
     response = self.client.post('/api/vehicles/', data=vehicle_data, format='json', HTTP_AUTHORIZATION=self.token) 
     self.assertEqual(response.status_code, 201) 

Wirklich gute Ressource, die ich verwendet habe, um mit diesem django-rest-framework-jwt tests ist

+0

'self.client = APIClient()' diese Zeile ist nicht erforderlich, da Sie von 'APITestCase' erben, die bereits vorhanden ist. –

Verwandte Themen