Модульное тестирование Django JSON View - PullRequest
10 голосов
/ 25 января 2011

Я пытаюсь написать некоторые модульные тесты для некоторых представлений Django json_view, и у меня возникают проблемы с передачей json_string в представление.Вчера я опубликовал связанный вопрос о передаче строки json в представление Django из JS, проблема заключалась в том, что в моем JS я просто передавал строку json, где мне нужно было передать строку в качестве атрибута объекта, потому что яне удалось сделать это, строка была взята в качестве ключа для результирующего запроса dict.У меня снова похожая проблема, за исключением того, что на этот раз это от юнит-теста Django до Django View.Вот упрощенная версия моего кода, которая дает тот же результат.

class MyTestCase(TestCase):
    def setUp(self):
        self.u = User.objects.create_user('test','test','test')
        self.u.is_active = True
        self.u.save()
        self.client.login(username='test',password='test')

    def test_create_object_from_form(self):
        """Test the creation of the Instance from the form data."""
        import json
        json_string json.dumps({'resource':{'type':'book','author':'John Doe'}})
        print(json_string)
        response = self.client.post(reverse('ajax_view'),
                                    {'form':json_string},'json')
        self.assetNotContains(response,'error')

, и вид выглядит следующим образом

@json_view
def ajax_view(request):
    """Process the incoming form data."""
    if request.method == 'POST':
        print(request.POST)
        form_data = json.loads(request.POST['form'])
        resource_data = form_data['resource']
        form = MyUserForm(resource_data)

        if form.is_valid():
        ...

Вот что выдают два оператора печати, когда тест выполняетсязапустить.Json_string -

{"resource": {"type": "book", "author": "John Doe"}}

, и запрос выглядит следующим образом:

<QueryDict: {u'{\'form\': \'{"resource": {"type": "book", "author": "John Doe"}}\'}': [u'']}>

Я новичок в JS и ajax, так что не беспокойтесь о том, чтобы навредить моей гордости, ответвозможно, так близко, что это может вскочить и укусить меня.

Ответы [ 2 ]

9 голосов
/ 25 января 2011

Окончательное редактирование

Первоначально я заявил, что заголовок HTTP_X_REQUESTED_WITH='XMLHttpRequest' был необходим при пост-вызове, но в настоящее время это неверно во время тестирования. Этот заголовок необходим для промежуточного программного обеспечения csrf, но csrf отключен в тестах. Тем не менее, я все еще считаю, что это хорошая практика для тестирования, даже если промежуточное ПО отключает csrf, так как большинство библиотек javascript уже передают этот заголовок по умолчанию при выполнении ajax. Кроме того, если другой фрагмент кода, который не отключен, когда-либо использует метод is_ajax, вам не нужно будет часами отлаживать ваш юнит-тест, чтобы выяснить, что заголовок отсутствует.

Проблема связана с типом контента, потому что когда django получает значение, отличное от text/html, он не использует обработку данных по умолчанию, которая используется для форматирования ваших данных, как в запросе: type=book&author=JohnDoe например.

Тогда фиксированный код:

response = self.client.post(reverse('ajax_view'),
                            {'form':json_string}, 
                            HTTP_X_REQUESTED_WITH='XMLHttpRequest')

Вот как я использую это сам:

post_data = { 
    "jsonrpc" : "2.0", "method": method, "params" : params, "id" : id }
return client.post('/api/json/', 
                    json.dumps(post_data), "text/json",            
                    HTTP_X_REQUESTED_WITH='XMLHttpRequest')

чтобы сделать JSON-RPC. Обратите внимание, что, поскольку я передаю тип содержимого, отличный от значения по умолчанию, мои данные передаются как есть в запросе на публикацию.

4 голосов
/ 25 января 2011

Спасибо @Eric_Fortin за то, что он включил меня в заголовок, однако это не решает мою проблему со словарем неверно сформированных запросов, использующим client.post.После того, как я сделал переход с POST на GET с заголовком XMLHttpRequest, мой словарь запросов сузился.Вот текущее решение:

response = self.client.get(reverse('ajax_view'),
                           {'form':json_string},'json',
                           HTTP_X_REQUESTED_WITH='XMLHttpRequest')

это только частичный ответ, так как этот запрос будет изменять данные на сервере и должен быть POST, а не GET.

Редактировать:

Вот последний код в моем тесте, который работает для передачи строки JSON через POST на мой взгляд:

response = self.client.post(reverse('ajax_view'),
                            {'form':json.dumps(json_dict)})

Теперь печать из представления показывает, что словарь запросовправильно сформирован.

<QueryDict: {u'form': [u'{"resource": {"status": "reviewed", "name": "Resource Test", "description": "Unit Test"}}']}>

Я нашел ответ, когда возился с одним из моих коллег, удалив content_type 'json', исправив неправильный словарь запросов.Проверяемое представление не использует и не вызывает HttpRequest.is_ajax (), отправка заголовка XMLHttpRequest не влияет на мою проблему, хотя включение заголовка будет представлять собой хорошую форму, поскольку этот пост является запросом ajax.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...