I have a Django Library application which has the following BookInstance Model:
class BookInstance(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4,help_text='Unique ID for this particular book across whole library')
book = models.ForeignKey('Book', on_delete=models.SET_NULL, null=True)
due_back = models.DateField(null=True, blank=True)
borrower = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True)
STATUS_MAINTENANCE = 'm'
STATUS_ON_LOAN = 'o'
STATUS_AVAILABLE = 'a'
STATUS_RESERVED = 'r'
LOAN_STATUS = (
(STATUS_MAINTENANCE, 'Maintenance'),
(STATUS_ON_LOAN, 'On loan'),
(STATUS_AVAILABLE, 'Available'),
(STATUS_RESERVED, 'Reserved'),
)
status = models.CharField(
max_length=1,
choices=LOAN_STATUS,
blank=True,
default=STATUS_MAINTENANCE,
help_text='Book availability',
)
class Meta:
ordering = ['due_back']
permissions = (("can_mark_returned", "Set book as returned"), ("can_create_book", "Create new book"), ("can_update_book", "Update book details"), ("can_delete_book", "Delete book"),)
# how to develop test case for this function
@property
def is_overdue(self):
if self.due_back and date.today() > self.due_back:
return True
return False
In my tests.py file, I have the test_object_name_is_name function to test it, however my coverage report shows that the function is not getting tested.
class BookInstanceModelTest(TestCase):
"""
Test case for Book Instance
"""
@classmethod
def setUpTestData(cls):
# Set up non-modified objects used by all test methods
test_user1 = User.objects.create_user(username='testuser1', password='1X<ISRUkw+tuK',
email='testuser1@test.com')
test_user2 = User.objects.create_user(username='testuser2', password='2HJ1vRV0Z&3iD',
email='testuser2@test.com')
test_author = Author.objects.create(first_name='William', last_name='Shakespeare')
test_book = Book.objects.create(title='Hamlet', author=test_author, summary='Published in 1990',
isbn='123456789123')
genre_objects_for_book = Genre.objects.all()
test_book.genre.set(genre_objects_for_book)
return_date1 = datetime.date.today()
BookInstance.objects.create(book=test_book, borrower=test_user1, due_back=return_date1,
status='o')
return_date2 = datetime.date.today() + datetime.timedelta(days=5)
BookInstance.objects.create(book=test_book, borrower=test_user2, due_back=return_date2,
status='o')
return_date3 = datetime.date.today() - datetime.timedelta(days=5)
BookInstance.objects.create(book=test_book, borrower=test_user2, due_back=return_date3,
status='o')
# test case I developed
def test_book_is_overdue(self):
last_date = datetime.date.today()
for book in BookInstance.objects.all():
if book.due_back == last_date:
self.assertTrue(True)
elif book.due_back > last_date:
self.assertTrue(True)
elif book.due_back < last_date:
self.assertFalse(False)
I have made a check whether the due_back is late or below the deadline, the Test executes successfully, and yet does not actually test the is_overdue() of BookInstance model. Please guide me how should I test this function correctly! Thanks
I think you misunderstood how test case works in django; you should prefix your test methods with test_
and then whatever name you want, but its not important for functionality nor it will call functions.
To test your property, you should call it in your test:
def test_book_is_overdue(self):
last_date = datetime.date.today()
for book in BookInstance.objects.all():
value = book.is_overdue
# test whatever you want