2014-04-15 28 views
16

Ho problemi testando un ViewSet:Django Rest Framework - Come testare ViewSet?

class ViewSetTest(TestCase): 
    def test_view_set(self): 
     factory = APIRequestFactory() 
     view = CatViewSet.as_view() 
     cat = Cat(name="bob") 
     cat.save() 

     request = factory.get(reverse('cat-detail', args=(cat.pk,))) 
     response = view(request) 

sto cercando di replicare la sintassi qui:

http://www.django-rest-framework.org/api-guide/testing#forcing-authentication

Ma penso che la loro visione AccountDetail è diverso dal mio ViewSet, così Sto ottenendo questo errore dall'ultima riga:

AttributeError: 'NoneType' object has no attributes 'items' 

C'è una sintassi corretta qui o sto mescolando su co ncepts? I miei test APIClient funzionano, ma sto usando la fabbrica qui perché alla fine vorrei aggiungere "request.user = some_user". Grazie in anticipo!

Oh, e il test del client funziona bene:

def test_client_view(self): 
    response = APIClient().get(reverse('cat-detail', args=(cat.pk,))) 
    self.assertEqual(response.status_code, 200) 

risposta

3

penso che sia la tua ultima riga. È necessario chiamare il CatViewSet come_view(). Vorrei andare con:

response = view(request) 

dato che è già definito view = CatViewSet.as_view()

EDIT:

Potete mostrare il vostro views.py? In particolare, che tipo di ViewSet hai usato? Sto scavando attraverso il codice DRF e sembra che tu non possa avere alcuna azione associata al tuo ViewSet, che sta facendo scattare l'errore.

+0

dispiace ho copiato ultima linea sbagliata, ho modificato per correggere questo errore – WBC

+0

Quale linea nella il codice sta lanciando l'errore? – Alex

+0

ultima riga, sono in grado di andare al debugger prima di esso, tutto è definito ma penso che forse c'è qualcosa di speciale nel passare la richiesta in ViewSet? – WBC

12

Credo di aver trovato la sintassi corretta, ma non è sicuro se è convenzionale (ancora nuovo a Django):

def test_view_set(self): 
    request = APIRequestFactory().get("") 
    cat_detail = CatViewSet.as_view({'get': 'retrieve'}) 
    cat = Cat.objects.create(name="bob") 
    response = cat_detail(request, pk=cat.pk) 
    self.assertEqual(response.status_code, 200) 

Così ora questo passa e posso assegnare request.user, che mi permette di personalizzare il metodo di recupero in CatViewSet per considerare l'utente.

7

Ho avuto lo stesso problema e sono riuscito a trovare una soluzione.

Guardando il codice sorgente, sembra che la vista si aspetta che ci sia un argomento 'azioni' che ha elementi di metodo (quindi, un ditt).

https://github.com/tomchristie/django-rest-framework/blob/master/rest_framework/viewsets.py#L69

Questo è dove l'errore che stai ricevendo proviene. Dovrai specificare le azioni dell'argomento con un dict contenente le azioni consentite per quel viewet, e quindi sarai in grado di testare correttamente la View.

La mappatura generale va:

{ 
    'get': 'retrieve', 
    'put': 'update', 
    'patch': 'partial_update', 
    'delete': 'destroy' 
} 

http://www.django-rest-framework.org/tutorial/6-viewsets-and-routers

Nel tuo caso si vorrà { 'ottenere': 'recuperare'} Come così:

class ViewSetTest(TestCase): 
    def test_view_set(self): 
     factory = APIRequestFactory() 
     view = CatViewSet.as_view(actions={'get': 'retrieve'}) # <-- Changed line 
     cat = Cat(name="bob") 
     cat.save() 

     request = factory.get(reverse('cat-detail', args=(cat.pk,))) 
     response = view(request) 

EDIT: Dovrai effettivamente specificare le azioni richieste. Codice e commenti modificati per riflettere questo.

3

ho trovato un modo per farlo senza bisogno di creare manualmente la viewset destra e dargli una mappatura azione:

from django.core.urlresolvers import reverse, resolve 
... 
url = reverse('cat-list') 
req = factory.get(url) 
view = resolve(url).func 
response = view(req) 
response.render() 
Problemi correlati