2011-12-20 16 views
27

Estoy trabajando en un proyecto de django que servirá como punto final para un webhook. El webhook enviará algunos datos JSON a mi punto final, que luego analizará esos datos. Intento escribir pruebas unitarias para ello, pero no estoy seguro de si estoy enviando el JSON correctamente.Enviando JSON usando el cliente de prueba django

Me pone "TypeError: índices de cadena deben ser enteros" en pipeline_endpoint

Aquí está el código:

# tests.py 
from django.test import TestCase 
from django.test.client import Client 
import simplejson 

class TestPipeline(TestCase): 

    def setUp(self): 
     """initialize the Django test client""" 
     self.c = Client() 

    def test_200(self): 
     json_string = u'{"1": {"guid": "8a40135230f21bdb0130f21c255c0007", "portalId": 999, "email": "[email protected]"}}' 
     json_data = simplejson.loads(json_string) 
     self.response = self.c.post('/pipeline-endpoint', json_data, content_type="application/json") 
     self.assertEqual(self.response.status_code, "200") 

y

# views.py 
from pipeline.prospect import Prospect 
import simplejson 

def pipeline_endpoint(request): 

    #get the data from the json object that came in 
    prospects_json = simplejson.loads(request.raw_post_data) 
    for p in prospects_json: 
     prospect = { 
      'email'   : p['email'], 
      'hs_id'   : p['guid'], 
      'portal'   : p['portalId'], 
     } 

Editar: rastreo conjunto.

====================================================================== 
ERROR: test_200 (pipeline.tests.TestPipeline) 
---------------------------------------------------------------------- 
Traceback (most recent call last): 
    File "F:\......\pipeline\tests.py", line 31, in test_200 
    self.response = self.c.post('/pipeline-endpoint', json_string, content_type="application/json") 
    File "C:\Python27\lib\site-packages\django\test\client.py", line 455, in post 
    response = super(Client, self).post(path, data=data, content_type=content_type, **extra) 
    File "C:\Python27\lib\site-packages\django\test\client.py", line 256, in post 
    return self.request(**r) 
    File "C:\Python27\lib\site-packages\django\core\handlers\base.py", line 111, in get_response 
    response = callback(request, *callback_args, **callback_kwargs) 
    File "F:\......\pipeline\views.py", line 18, in pipeline_endpoint 
    'email'   : p['email'], 
TypeError: string indices must be integers 

---------------------------------------------------------------------- 
Ran 1 test in 0.095s 

FAILED (errors=1) 
Destroying test database for alias 'default'... 
+0

¡Por favor muestre todo el rastreo –

+0

actualizado con traceback! –

+1

¿Es ... porque debería usar 'json.dumps' (con un objeto python) en lugar de' json.loads' (con una cadena), y por lo tanto está enviando a través de un objeto python con la solicitud de su cliente, en lugar de que un objeto python serializado como un objeto json? – mrmagooey

Respuesta

2

Puede usuario iteritems en los diccionarios de bucle

for index, p in prospects_json.iteritems(): 
    prospect={ 
    'email': p['email'], 
    } 

o alternativamente

for index in prospect_json: 
    prospect={ 
    'email': prospect_json[ index ]['email'] 
    } 
+1

Gracias por el recordatorio iteritems(), pero todavía estoy teniendo un JSONDecodeError. Todo se ve raro con el JSON. –

+0

No, de hecho funcionó bien en el caparazón. ¿Puedes actualizar tu rastreo? – czarchaic

36

@mrmagooey es correcto

def test_your_test(self): 
    python_dict = { 
     "1": { 
      "guid": "8a40135230f21bdb0130f21c255c0007", 
      "portalId": 999, 
      "email": "[email protected]" 
     } 
    } 
    response = self.client.post('/pipeline-endpoint/', 
           json.dumps(python_dict), 
           content_type="application/json") 

uso json.dumps en lugar de json.loads

7

Siempre puede usar el HttpRequest.body que carga los datos de solicitud sin procesar. De esta forma puede manejar su propio procesamiento de datos.

c = Client() 
json_str= json.dumps({"data": {"id": 1}}) 
c.post('/ajax/handler/', data= json_str, content_type='application/json', 
             HTTP_X_REQUESTED_WITH='XMLHttpRequest') 


def index(request): 
    .... 
    print json.loads(request.body) 
6

Probar:

+0

¡Funciona bien también con 'GET'! ¡Gracias! – Giordano

1

rest_framework 's APIClient se encarga de dumping dict-JSON y se establece el tipo de contenido adecuado al pasar format='json'.

from rest_framework import status 
from rest_framework.test import APIClient, APITestCase 


class MyTestCase(APITestCase): 
    client_class = APIClient 
    url = '/url' 

    def post(self, payload url=None): 
     """ 
     Helper to send an HTTP post. 

     @param (dict) payload: request body 

     @returns: response 
     """ 
     if url is None: 
      url = self.url 

     return self.client.post(url, payload, format='json') 

    def test_my_function(self): 
     payload = { 
      'key': 'value' 
     } 
     response = self.post(payload) 
     self.assertEqual(status.HTTP_200_OK, response.status_code) 
Cuestiones relacionadas