pythondjangodjango-rest-frameworkdjango-validation

How to write unit test ValidationError case in response by use client.post()?


I have a model with a time validator raise ValidationError('End time cannot be earlier than start time')

So I want to write a unit test using client.post() with data invalid (from_time > to_time), and I expected ValidationError to appear in this test.

    raise ValidationError('End time cannot be earlier than start time')
django.core.exceptions.ValidationError: ['End time cannot be earlier than start time']

Solution

  • you can take a look at the document example on how to write test case https://docs.djangoproject.com/en/dev/topics/testing/tools/#example. In your case it would be like so(notice that this is just an example, so modify to fit your case):

    This is for validating from serializer/api of 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')
    

    This is for validating from model validator(doc):

    for example you have your model validator like so in your model:

    def custom_validator(value):
        if value.end_time < value.start_time:
          raise ValidationError('End time cannot be earlier than start time')
    

    Your unit test will be like this, use python assertRaisesRegex() to check for python ValidationError type:

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