Trying to test selector layer im my app, but django dont pass simle test. Querysets looks quite similar, maybe i lost something.
test.py
from django.test import TestCase
from books.models import Author, Book
from books.selectors import get_books
class SelectorTest(TestCase):
def setUp(self):
self.author = Author.objects.create(
name='test_author'
)
self.book = Book.objects.create(
name='test_book',
category='Drama',
release_date='2001-01-01',
author=self.author,
is_read=True
)
def test_get_books(self):
self.assertEqual(get_books(), Book.objects.all())
selectors.py
from django.db.models.query import QuerySet
from books.models import Book
def get_books() -> QuerySet[Book]:
"""
Return all objects of Book model.
"""
books = Book.objects.all()
return books
assertion error
AssertionError: <QuerySet [<Book: test_book>]> != <QuerySet [<Book: test_book>]>
CodePudding user response:
To test that two querysets return the same objects but not necessarily in the same order (assuming both query the same underlying Model, of course):
qs1 = Book.objects.all()
qs2 = get_books()
pk1 = qs1.values_list( 'pk', flat=True)
pk2 = q2s.values_list( 'pk', flat=True)
self.assertEqual ( set(pk1), set(pk2) )
This makes a reasonably useful message when the test fails. You get the pks which are in one and not the other identified, not just a not equal" message.
I think if you use list()
instead of set()
you get to check that both return the same objects in the same order.
CodePudding user response:
You can use the TransactionTestCase.assertQuerysetEqual
assertion from Django's TestCase
class. Check the documentation here.
In your case:
# …
def test_get_books(self):
self.assertQuerysetEqual(get_books(), Book.objects.all())