2014-12-14 9 views
13

Sto usando Python 3.4 e Django 1.7. Ho una vista che restituisce JsonResponse.Come usare Django's assertJSONEqual per verificare la risposta della vista restituendo JsonResponse

def add_item_to_collection(request): 
    #(...) 
    return JsonResponse({'status':'success'}) 

voglio verificare se questo punto di vista i rendimenti corretta risposta utilizzando test di unità:

class AddItemToCollectionTest(TestCase): 

    def test_success_when_not_added_before(self): 
     response = self.client.post('/add-item-to-collection') 
     self.assertEqual(response.status_code, 200) 
     self.assertJSONEqual(response.content, {'status': 'success'}) 

Tuttavia la linea assertJSONEqual() solleva un'eccezione:

Error 
Traceback (most recent call last): 
    File "E:\Projects\collecthub\app\collecthub\collecting\tests.py", line 148, in test_success_when_added_before 
    self.assertJSONEqual(response.content, {'status': 'OK'}) 
    File "E:\Projects\collecthub\venv\lib\site-packages\django\test\testcases.py", line 675, in assertJSONEqual 
    data = json.loads(raw) 
    File "C:\Python34\Lib\json\__init__.py", line 312, in loads 
    s.__class__.__name__)) 
TypeError: the JSON object must be str, not 'bytes' 

Qual è Thet corretto modo di verificare contenuto della risposta, quando la risposta contiene JSON? Perché ottengo un errore di tipo quando provo a confrontare il valore grezzo con un valore in assertJSONEqual()?

risposta

17

Sembra che si sta lavorando con Python 3 in modo avrete bisogno di trasformare response.content in un UTF-8 stringa codificata prima di passarlo al self.assertJSONEqual:

class AddItemToCollectionTest(TestCase): 

    def test_success_when_not_added_before(self): 
     response = self.client.post('/add-item-to-collection') 
     self.assertEqual(response.status_code, 200) 
     self.assertJSONEqual(
      str(response.content, encoding='utf8'), 
      {'status': 'success'} 
     ) 

Se si desidera supportare simultaneamente sia Python 2.7 e Python 3, utilizzare la libreria six compatibilità che django ships with:

from __future__ import unicode_literals 
from django.utils import six 

class AddItemToCollectionTest(TestCase): 

    def test_success_when_not_added_before(self): 
     response = self.client.post('/add-item-to-collection') 
     self.assertEqual(response.status_code, 200) 

     response_content = response.content 
     if six.PY3: 
      response_content = str(response_content, encoding='utf8') 

     self.assertJSONEqual(
      response_content, 
      {'status': 'success'} 
     ) 
+5

Invece di 'str', questo funziona anche:' response.content.decode ("utf-8") ' – jaywink

5

Analogamente soluzione per respondcreate, è anche possibile utilizzare di Django force_text (disponibile dal vers ion 1.5), per una soluzione multipiattaforma più corta:

from __future__ import unicode_literals 
from django.utils.encoding import force_text 

class AddItemToCollectionTest(TestCase): 

    def test_success_when_not_added_before(self): 
     response = self.client.post('/add-item-to-collection') 
     self.assertEqual(response.status_code, 200) 

     self.assertJSONEqual(force_text(response.content), {'status': 'success'}) 
Problemi correlati