Home > Mobile >  How can I unit test saving user input in Django?
How can I unit test saving user input in Django?

Time:03-31

I am working on a small project and I want to be able to test the post methods, saving to the database if the email does not exist, and rendering to index.html for the view below. I've looked at YouTube videos and blog tutorials and I can't seem to find the answer that I am looking for. I have included the Model, View, and my current tests.

Model:

class EmailList(models.Model):
    email = models.TextField(unique=True)

View:

def home(request):
    # Join Email List
    if request.method == 'POST':
        if request.POST.get('email'):
            email = request.POST.get('email')
            if not EmailList.objects.filter(email=email).exists():
                emailInput = EmailList()
                emailInput.email = email
                emailInput.save()
            return render(request, 'email/index.html', {})
    else:
        return render(request, 'email/index.html', {})

Test I have so far:

from django.test import TestCase
from tasckq.models import EmailList   

class HomeViewTest(TestCase):
        @classmethod
        def setUpTestData(cls):
            # Create a new email to test
            EmailList.objects.create(email="[email protected]")
    
        def test_home_view_url_exists_at_desired_location(self):
            response = self.client.get('')
            self.assertEqual(response.status_code, 200)
    
        def test_home_view_post_request_method(self):
            response = self.client.post('', {'email' : '[email protected]'})
            self.assertEqual(response.status_code, 200)
    
        def test_home_view_save_email(self):
            self.assertEqual(EmailList.objects.count(), 1)

CodePudding user response:

You should not create an instance of EmailList in your setUpTestData method, because you want to check if your view correctly creates a new instance, right now you manually create a new one before testing. Try this:

from django.test import TestCase
from tasckq.models import EmailList   

class HomeViewTest(TestCase):
   def test_home_view(self):
       # Tests the get method
       response = self.client.get('')
       self.assertEqual(response.status_code, 200)
       self.assertTemplateUsed(response, template_name='email/index.html')
       
       # Tests the post method
       
       email = '[email protected]'
       response = self.client.post('', {'email' : email})
       self.assertEqual(response.status_code, 200)
       self.assertTemplateUsed(response, template_name='email/index.html')
       # A new EmailList instance has been successfully created
       self.assertTrue(EmailList.objects.filter(email=email).exists())
       
       response = self.client.post('', {'email' : email})
       self.assertEqual(response.status_code, 200)
       self.assertTemplateUsed(response, template_name='email/index.html')
       # A new EmailList instance has not been created because the email was already in use
       self.assertEqual(EmailList.objects.count(), 1)
  • Related