2011-12-20 22 views
27

Pracuję nad django projektem, który będzie służyć jako punkt końcowy dla webhooka. Webhook będzie POST niektóre dane JSON do mojego punktu końcowego, który następnie przeanalizuje te dane. Próbuję napisać testy jednostkowe, ale nie jestem pewien, czy wysyłam JSON poprawnie.Wysyłanie JSON za pomocą klienta testowego django

ciśgle "TypeError: indeksy łańcuchowe muszą być liczbami całkowitymi" w pipeline_endpoint

Oto kod:

# 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") 

i

# 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'], 
     } 

Edit: cały traceback.

====================================================================== 
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

Proszę pokazać cały okres śledzenia –

+0

zaktualizowany przy pomocy traceback! –

+1

Czy to ... ponieważ powinieneś używać 'json.dumps' (z obiektem Pythona) zamiast' json.loads' (z ciągiem znaków), a więc wysyłasz obiekt Pythona na żądanie klienta niż obiekt Pythona zserializowany jako obiekt JSON? – mrmagooey

Odpowiedz

2

Można użytkownikowi iteritems na słowników do pętli

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

lub alternatywnie

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

Dzięki za przypomnienie iteritems(), ale nadal mam błąd JSONDecodeError. Coś wygląda dziwnie z JSON. –

+0

Nie, w rzeczywistości zadziałało dobrze w powłoce. Czy możesz zaktualizować swój system śledzenia? – czarchaic

36

@mrmagooey ma rację

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") 

użycie json.dumps zamiast json.loads

7

Zawsze można użyć HttpRequest.body, który ładuje dane żądania żądania. W ten sposób możesz obsłużyć własne przetwarzanie danych.

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

Spróbuj:

+0

Działa również z funkcją "GET"! Dziękuję Ci! – Giordano

1

rest_framework „s APIClient dba o dumping dict do JSON i ustawia odpowiedni typ treści przekazując 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) 
Powiązane problemy