TypeError: объект 'NoneType' не может быть подписан в тестах юнитов Django для сообщения - PullRequest
0 голосов
/ 14 января 2019

Я пытаюсь выполнить модульный тест для представления, которое возвращает сообщение, когда в базе данных дублируется какой-либо ввод. Это выдает ошибку TypeError: 'NoneType' object is not subscriptable

Вот вид

@login_required
def worker_create(request):
    worker_create_form = WorkerCreateForm(request.POST)
    if request.method == 'POST':
        if worker_create_form.is_valid():
            form = worker_create_form.save(commit=False)
            phone = form.phone
            check_phone = Worker.objects.filter(phone=phone)
            if check_phone.count() != 0:
                messages.error(request, 'رقم الهاتف مستخدم من قبل')
            else:
                form.save()
                return redirect('worker_list')
    else:
        worker_create_form = WorkerCreateForm(request.POST)
    context = {
        'worker_create_form': worker_create_form,
    }
    return render(request, 'erp_system/worker/create.html', context)

и вот тесты , которые я создал для него

class WorkerCreateTest(TestCase):
    def setUp(self):
        User.objects.create_user(username='test_user', email='test@gmail.com', password='test_password')
        branch = Branch.objects.create(name='test branch')
        Worker.objects.create(name="ay btngan ", phone='01207199086', branch=branch)

    def test_get_request_unauthenticated(self):
        response = self.client.get(reverse('worker_create'))
        url = reverse('worker_create')
        self.assertRedirects(response, '/login/?next=' + url)

    def test_get_request_authenticated(self):
        self.client.login(username='test_user', password='test_password')
        response = self.client.get(reverse('worker_create'))
        self.assertEqual(response.status_code, 200)
        self.assertTemplateUsed('erp_system/worker/create.html')

    def test_post_request_empty_data(self):
        self.client.login(username='test_user', password='test_password')
        response = self.client.post(reverse('worker_create'), {})
        self.assertFormError(response, 'worker_create_form', 'name', 'This field is required.')
        self.assertFormError(response, 'worker_create_form', 'phone', 'This field is required.')
        self.assertFormError(response, 'worker_create_form', 'branch', 'This field is required.')

    def test_post_request_invalid_data(self):
        self.client.login(username='test_user', password='test_password')
        branch = Branch.objects.create(name='test again ')
        name = 'just a name'
        for i in range(300):
            name += 'h'
        response = self.client.post(reverse('worker_create'),
                                    {'name': name, 'phone': '01207199086', 'branch': branch.id})
        self.assertEqual(response.status_code, 200)

    def test_post_request_duplicated_phone(self):
        self.client.login(username='test_user', password='test_password')
        branch = Branch.objects.create(name='test again ')
        response = self.client.post(reverse('worker_create'),
                                    {'name': 'test worker', 'phone': '01207199086', 'branch': branch.id})
        print(response)
        messages = list(response.context['messages'])
        self.assertEqual(len(messages), 1)
        self.assertEqual(str(messages[0]), 'رقم الهاتف مستخدم من قبل')

    def test_post_request_valid_data(self):
        self.client.login(username='test_user', password='test_password')
        branch = Branch.objects.create(name='test branch1234')
        name = 'new valid name'
        response = self.client.post(reverse('worker_create'),
                                    {'name': name, 'branch': branch.id, 'phone': '0151951115'})
        self.assertEqual(response.status_code, 302)

Важно Когда я добавил print(response), я заметил, что это дает мне HttpResponseRedirect, а не просто HttpResponse, что означает отсутствие заданного контекста. Почему это с помощью перенаправления здесь!?

1 Ответ

0 голосов
/ 14 января 2019

В своем тесте test_post_request_duplicated_phone вы отправляете запрос POST к worker_create и ожидаете получить ошибку, поскольку для данной phone.

уже существует запись.

Документация по тестам [Django-doc] однако упоминает, что:

A TestCase, с другой стороны, не усекает таблицы после теста. Вместо этого он заключает тестовый код в транзакцию базы данных , которая откатывается в конце теста . Это гарантирует, что откат в конце теста вернет базу данных в исходное состояние .

Таким образом, это означает, что, если вы не реализуете некоторые «уловки» для предотвращения этого, побочные эффекты, которые имеет один тест (для базы данных), исчезнут, когда вы введете второй тест. Это имеет смысл, поскольку переупорядочивание тестов не должно привести к другому результату.

Однако вы можете заранее создать такой Worker объект в своем тесте и, таким образом, убедиться, что тест действительно даст ошибку:

def test_post_request_duplicated_phone(self):
    self.client.login(username='test_user', password='test_password')
    branch = Branch.objects.create(name='test again ')
    <b>Worker.objects.create(name=" just a name ", phone='01207199086', branch=branch)</b>
    response = self.client.post(reverse('worker_create'),
                                {'name': 'test worker', 'phone': '01207199086', 'branch': branch.id})
    print(response)
    messages = list(response.context['messages'])
    self.assertEqual(len(messages), 1)
    self.assertEqual(str(messages[0]), 'رقم الهاتف مستخدم من قبل')
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...