Как написать модульный тест ValidationError в ответе с помощью client.post()
У меня есть модель с валидатором времени raise ValidationError('End time cannot be earlier than start time')
Я хочу написать модульный тест, используя client.post()
с недействительными данными (from_time > to_time), и я ожидал, что ValidationError появится в этом тесте.
Вы можете взглянуть на пример документа о том, как написать тестовый пример https://docs.djangoproject.com/en/dev/topics/testing/tools/#example. В вашем случае это будет выглядеть так (обратите внимание, что это всего лишь пример, поэтому измените его в соответствии с вашим случаем):
Это для проверки из сериализатора/api DRF:
import unittest
from django.test import Client
import datetime
class SimpleTest(unittest.TestCase):
def setUp(self):
# Every test needs a client.
self.client = Client()
def test_invalid_date(self):
# Issue a POST request.
response = self.client.post(
'/your/path/url',
{
'start_time': datetime.datetime(2020, 5, 17),
'end_time': datetime.datetime(2020, 5, 15) #notice end_time smaller than start_time
},
)
self.assertEqual(response.status_code, 400)
# Check that the rendered context json have error message.
self.assertEqual(response.json()['key']['path']['to']['error']['message'], 'End time cannot be earlier than start time')
Для валидации из валидатора модели(doc):
Например, в вашей модели валидатор модели выглядит следующим образом:
def custom_validator(value):
if value.end_time < value.start_time:
raise ValidationError('End time cannot be earlier than start time')
Ваш модульный тест будет выглядеть следующим образом, используйте python assertRaisesRegex()
для проверки типа python ValidationError:
import unittest
from django.test import Client
import datetime
class SimpleTest(unittest.TestCase):
def test_invalid_date(self):
with self.assertRaisesRegex(ValidationError, 'End time cannot be earlier than start time'):
your_model = YourModel(
start_time=datetime.datetime(2020, 5, 17),
end_time=datetime.datetime(2020, 5, 15)
)
your_model.full_clean()
При использовании pytest-django ваш тест будет выглядеть следующим образом:
from datetime import datetime, timedelta
def test_error_when_to_time_before_from_time(db, admin_client):
invalid_data = {
"from_time": datetime.today(),
"to_time": datetime.today() - timedelta(days=2),
}
response = admin_client.post("<url-to-endpoint>", data=invalid_data)
assert response.status_code == 400
assert "End time cannot be earlier than start time" in response.content.decode()
Pytest-django предоставляет вам авторизованного клиента администратора и создает временную базу данных в зависимости от ваших текущих миграций для каждого теста. После теста изменения снова удаляются.
Я также добавил "TEST_REQUEST_DEFAULT_FORMAT": "json",
в словарь REST_FRAMEWORK
в settings.py
.