Search code examples
python-3.xpycharmdjango-unittestdjango-4.0

I want test the post method by django


I created a "Like" function that works properly. good. good. good. enter image description here

# a test file
from django.test import TestCase
from django.urls import reverse

from register.models import User
from vietnam_research.models import Articles, Likes
class TestView(TestCase):
    @classmethod
    def setUpTestData(cls):
        User.objects.create_user(email='[email protected]').set_password('12345')
        user = User.objects.get(email='[email protected]')
        Articles.objects.create(title='Hello', note='How are you', user=user)

    def test_click_good_button(self):
        user = User.objects.get(email='[email protected]')
        response = self.client.post(reverse('vnm:likes', kwargs={'user_id': 1, 'article_id': 1}), follow=True)
        self.assertEqual(200, response.status_code)

        print('Articles.objects.all().count(): ', Articles.objects.all().count())
        print('Likes.objects.all().count(): ', Likes.objects.all().count())
        self.assertTrue(Likes.objects.filter(user=user).exists())

# model
class Articles(models.Model):
    title = models.CharField(max_length=200)
    note = models.TextField()
    user = models.ForeignKey(get_user_model(), on_delete=models.CASCADE)
    created_at = models.DateTimeField(auto_now_add=True)


class Likes(models.Model):
    articles = models.ForeignKey(on_delete=models.CASCADE)
    user = models.ForeignKey(get_user_model(), on_delete=models.CASCADE)
    created_at = models.DateTimeField(auto_now_add=True)
# views.py
class LikesUpdateView(LoginRequiredMixin, UpdateView):
    def post(self, request, *args, **kwargs):
        print(json.loads(request.body), json.loads(request.body).get('status'))
        try:
            user = User.objects.get(pk=kwargs['user_id'])
            article = Articles.objects.get(pk=kwargs['article_id'])
            like = Likes.objects.filter(user=user, articles=article)
            if not like.exists():
                Likes.objects.create(user=user, articles=article)
            else:
                like.delete()
            return JsonResponse({"status": "responded by views.py"})
        except User.DoesNotExist:
            logging.critical('invalid user')
        except Articles.DoesNotExist:
            logging.critical('invalid article')
# urls.py
urlpatterns = [
    path('', index, name='index'),
    path('likes/<int:user_id>/<int:article_id>/', LikesUpdateView.as_view(), name='likes'),
      :
]
# console
D:\venv\Scripts\python.exe "C:\pycharm\django_test_manage.py" test tests.test_views.TestView.test_click_good_button D:\mysite
Testing started at 22:28 ...
Creating test database for alias 'default'...
Found 1 test(s).
System check identified no issues (0 silenced).


Articles.objects.all().count():  1
Destroying test database for alias 'default'...  <<< this!!!!!!!
Likes.objects.all().count():  0

Failure
Traceback (most recent call last):
  File "D:\OneDrive\dev\portfolio\mysite\vietnam_research\tests\test_views.py", line 36, in test_click_good_button
    self.assertTrue(Likes.objects.filter(user=user).exists())
AssertionError: False is not true

After being posted, an insert should be issued to the 'likes' model.
But in reality, the database is destroyed before the 'likes' model has more records.
Is there something missing when testing the post method?

After several rounds of testing, the "Like!" model counts to zero, we found that the database could be corrupted. However, no records for the 'likes' model occurred.

# console
Articles.objects.all().count():  1
Likes.objects.all().count():  0
Destroying test database for alias 'default'...

Solution

  • It took a long time, but I finally solved it!

    from django.core.exceptions import ObjectDoesNotExist
    from django.test import TestCase, Client
    from django.urls import reverse
    
    from register.models import User
    from vietnam_research.models import Articles, Likes
    
    
    class TestView(TestCase):
        def setUp(self):
            self.password_plane = '<PASSWORD>'
            self.user = User.objects.create_user(email='[email protected]')
            self.user.set_password(self.password_plane)
            self.user.save()
            self.article = Articles.objects.create(title='Hello', note='How are you', user=self.user)
    
        def test_can_create_likes(self):
            logged_in = self.client.login(email=self.user.email, password=self.password_plane)
            self.assertTrue(logged_in)
    
            # create 3 users
            emails = ['[email protected]', '[email protected]', '[email protected]']
            [User.objects.create_user(email=x).set_password(self.password_plane) for x in emails]
    
            # already got 'likes' from 3 users
            [Likes.objects.create(articles=self.article, user=User.objects.get(email=x)) for x in emails]
            self.assertEqual(3, Likes.objects.filter(articles=self.article).count())
    
            # click the 'likes' then the count should be 4
            # response = client.post(reverse('vnm:likes', kwargs={'user_id': 1, 'article_id': 1}), follow=True)
            response = self.client.post('/likes/create/1/1/')
            self.assertEqual(4, Likes.objects.filter(articles=self.article).count())
            self.assertEqual(201, response.status_code)