django: контрольный пример для функции @property модели - PullRequest
0 голосов
/ 20 декабря 2018

У меня есть приложение Django Library, которое имеет следующую модель BookInstance:

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

В моем файле tests.py У меня есть функция test_object_name_is_name для проверки , однако мое покрытиеотчет показывает, что функция не проходит тестирование.

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)

Я проверил, опоздал ли срок возврата или опоздал ли он, тест успешно выполнен, и все же на самом деле не тестирует is_overdue() модели BookInstance. Пожалуйста, укажите, как правильно проверить эту функцию!Спасибо

Ответы [ 3 ]

0 голосов
/ 20 декабря 2018

Вот правильный тестовый пример.Обратите внимание, что 1 / я создаю метод тестирования для каждого условия (я проверяю каждое условие изолированно) и 2 / я создаю книгу для тестирования в самом методе теста (делает тест намного более наглядным и читаемым).Я использую setUp() только для приборов, которые необходимы для испытаний, но НЕ являются частью самого теста.Также я добавляю более явные сообщения об ошибках в вызовах self.assertXXX (потому что наличие «False is True», так как отчет о неудачном тесте на самом деле не помогает).

class BookInstanceModelTest(TestCase):
    def setUp(self):
        self.test_user1 = User.objects.create_user(
            username='testuser1', 
            password='1X<ISRUkw+tuK',
            email='testuser1@test.com'
        )

        self.test_author = Author.objects.create(
           first_name='William', 
           last_name='Shakespeare'
        )

        self.test_book = Book.objects.create(
            title='Hamlet', 
            author=self.test_author, 
            summary='Published in 1990',                                       
            isbn='123456789123'
        )

        genre_objects_for_book = Genre.objects.all()
        self.test_book.genre.set(genre_objects_for_book)


    def test_book_is_not_overdue_if_due_back_date_is_today(self)            
        due_date = datetime.date.today()
        book = BookInstance.objects.create(
           book=self.test_book, 
           borrower=self.test_user1, 
           due_back=due_date, 
           status='o'
        )
        self.assertFalse(book.is_overdue, "book should not be overdue")


    def test_book_is_not_overdue_if_due_back_date_is_later_than_today(self):
        due_date = datetime.date.today() + datetime.timedelta(days=5)
        book = BookInstance.objects.create(
           book=self.test_book, 
           borrower=self.test_user1, 
           due_back=due_date, 
           status='o'
        )
        self.assertFalse(book.is_overdue, "book should not be overdue")


    def test_book_is_not_overdue_if_due_back_date_is_none(self):
        due_date = None
        book = BookInstance.objects.create(
           book=self.test_book, 
           borrower=self.test_user1, 
           due_back=due_date, 
           status='o'
        )
        self.assertFalse(book.is_overdue, "book should not be overdue")


    def test_book_is_overdue_if_due_back_date_is_past(self):
        due_date = datetime.date.today() - datetime.timedelta(days=5)
        book = BookInstance.objects.create(
           book=self.test_book, 
           borrower=self.test_user1, 
           due_back=due_date, 
           status='o'
        )
        self.assertTrue(book.is_overdue, "book should be overdue")
0 голосов
/ 21 марта 2019

Вы можете просто создать экземпляр и получить свойство из этого экземпляра.

instance = BookInstance(due_back=datetime.today())

# Then property can be accessed like this
instance.is_overdue 
0 голосов
/ 20 декабря 2018

Я думаю, вы неправильно поняли, как работает тестовый пример в django;вы должны добавить к своим методам тестирования префикс 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
...