'How to mock the count of likes for Django testing

I need to test this view:

class ShowHomePageView(views.TemplateView):
    template_name = 'home_page.html'

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        books = Book.objects.prefetch_related('likes'). \
                    filter(owner__isnull=False). \
                    annotate(like_count=Count('likes')). \
                    order_by('-like_count', 'title'). \
                    all()[:3]
        context['books_to_show'] = books
        return context

This is my model:

class Book(models.Model):
    TITTLE_MAX_LENGTH = 64
    AUTHOR_MAX_LENGTH = 64
    UPLOAD_PICTURE_MAX_SIZE_IN_MB = 2

    title = models.CharField(
        max_length=TITTLE_MAX_LENGTH,
    )

    author = models.CharField(
        max_length=AUTHOR_MAX_LENGTH,
    )

    category = models.ForeignKey(
        to=Category,
        null=True,
        blank=True,
        default='',
        on_delete=models.SET_DEFAULT,
    )

    image = CloudinaryField(
        "Image",
        null=True,
        blank=True,
        transformation={"quality": "auto:eco"},
        overwrite=True,
    )

    owner = models.ForeignKey(
        to=get_user_model(),
        on_delete=models.SET_NULL,
        null=True,
        blank=True,
        related_name='own_books',
    )

    ex_owners = models.ManyToManyField(
        to=get_user_model(),
        related_name='ex_books',
        blank=True,

    )

    previous_owner = models.ForeignKey(
        to=get_user_model(),
        related_name='books_to_send',
        null=True,
        blank=True,
        on_delete=models.SET_NULL
    )

    next_owner = models.ForeignKey(
        to=get_user_model(),
        related_name='book_on_a_way',
        null=True,
        blank=True,
        on_delete=models.SET_NULL
    )

    likes = models.ManyToManyField(
        to=get_user_model(),
        related_name='liked_books',
        blank=True,
    )

    is_tradable = models.BooleanField(
        default=True,
    )

    @property
    def likes_count(self):
        return len(self.likes.all())

    def __str__(self):
        return f'"{self.title}" by {self.author}'

    class Meta:
        ordering = ['title']

    def get_absolute_url(self):
        return reverse('book_details', kwargs={'pk': self.pk})

I have no idea how to test if the view gets the top 3 most liked books. I will easily create some books, but I do not know how to mock the value for likes count. I could create manually a lot of users add them to the book.likes but hope there is another smarter way to do it. Can you give me some clues?



Solution 1:[1]

You can use the model_mommy or factory_boy to create a dummy objects. After the create some objects you can mock the functions.

with patch('path_your_model.Book.likes_count', return_value=3):
     # your test code

and one more thing there is an orm function to count objects.

@property
def likes_count(self):
    return self.likes.all().count()

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 jackquin