Отправка JSON с помощью тестового клиента django
Я работаю над проектом django, который будет служить конечной точкой для веб-камеры. Webhook отправит POST некоторые данные JSON на мою конечную точку, которая затем проанализирует эти данные. Я пытаюсь написать для него единичные тесты, но я не уверен, правильно ли отправил JSON.
Я продолжаю получать "TypeError: строковые индексы должны быть целыми числами" в pipe_endpoint
Здесь код:
# 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")
и
# 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'],
}
Изменить: целая трассировка.
======================================================================
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'...
Ответы
Ответ 1
@mrmagooey прав
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")
используйте json.dumps
вместо json.loads
Ответ 2
Вы всегда можете использовать HttpRequest.body, который загружает необработанные данные запроса. Таким образом, вы можете обрабатывать свою собственную обработку данных.
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)
Ответ 3
Try:
self.client.generic('POST', '/url', json.dumps({'json': 'object'})
Ответ 4
Пользовательские словари iteritems
на словарях на цикл
for index, p in prospects_json.iteritems():
prospect={
'email': p['email'],
}
или, альтернативно,
for index in prospect_json:
prospect={
'email': prospect_json[ index ]['email']
}
Ответ 5
rest_framework
APIClient
выполняет сброс dict
в JSON
и устанавливает правильный тип содержимого, передавая 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)