Получение ошибки при издевательстве datetime.datetime.now () - PullRequest
2 голосов
/ 11 марта 2020

Я новичок в Python. Я пытаюсь смоделировать datetime.datetime.now (), но он не работает:

class Myclass:

   def update(self):

     time = datetime.datetime.now().strftime("%s")
     ...

Вышеуказанная функция находится в mypackage/my_class.py

. из этого поста ( Попытка смоделировать datetime.date.today (), но не работает ):

@patch('mypackage.my_class.Myclass.datetime')
def test_update(self, datetime_mock):
  datetime_mock.datetime.now.return_value=datetime.datetime(2020,1,1,1,1,1,1)

Я получаю сообщение об ошибке следующим образом:

E           AttributeError: <class 'mypackage.my_class.Myclass'> does not have the attribute 'datetime'

Затем я изменил патч, как показано ниже:

@patch('datetime')
def test_update(self, datetime_mock):
  datetime_mock.datetime.now.return_value=datetime.datetime(2020,1,1,1,1,1,1)

Теперь я получаю сообщение об ошибке, как показано ниже:

venv/lib/python3.6/site-packages/mock/mock.py:1591: in _get_target
    target, attribute = target.rsplit('.', 1)
E   ValueError: not enough values to unpack (expected 2, got 1)

E   TypeError: Need a valid target to patch. You supplied: 'datetime'

Ответы [ 2 ]

2 голосов
/ 11 марта 2020

Вы можете использовать freeze_time из модуля freezegun. Я изменил update(), чтобы создать строку даты и времени для удобства чтения в этом тесте

class MyClass:
    def update(self):
        self.time = datetime.datetime.now().strftime("%Y-%m-%d %H:%M")

from freezegun import freeze_time


class TestMyClass:
    @freeze_time("2020-03-01 12:31")
    def test_update(self):
        my_class = MyClass()
        my_class.update()
        assert my_class.time == "2020-03-01 12:31"

Надеюсь, это поможет!

0 голосов
/ 11 марта 2020

В вашем первом примере вы пытаетесь смоделировать несуществующий объект. Ваш Myclass не имеет datetime. Вы хотите издеваться над встроенным datetime, чтобы ваш второй подход был удачным, но вы пытаетесь смоделировать весь пакет, который AFAIK невозможен. Я также не уверен, что вы можете смоделировать объект и одновременно использовать его в тесте, если только вы не используете менеджер контекста, поэтому мое решение будет таким:

from unittest.mock import patch, MagicMock

def test_update():
    expected_datetime = datetime.datetime(2020, 1, 1, 1, 1, 1, 1)

    with patch.object(datetime, 'datetime') as datetime_mock:
        datetime_mock.now.return_value = expected_datetime
        # ...calls to the code you test and assertions...
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...