Как издеваться над модулями python, патч не находит атрибута - PullRequest
1 голос
/ 20 марта 2019

В функции я использую uuid1, которую я хочу патчить.

def myFunction():
     my_value = uuid4.int
     smth else..

Я хочу иметь возможность смоделировать my_value, чтобы он всегда возвращал одно и то же число в моем модульном тесте, потому что он мне нужен для дальнейшего использования. Я пытался сделать:

 @patch('folder.myFunction.uuid4')
 def test_myFunction(self, mock_value):
      mock_value.return_value = 22222

Но выдает ошибку, говорящую, что myFunction не имеет uuid4 в качестве атрибута.

Как мне высмеять его значение?

Ответы [ 2 ]

1 голос
/ 20 марта 2019

Полученная ошибка верна.Ваша функция не имеет атрибута uuid4.

Я читаю между строк, предполагая, что uuid4 - это метод модуля uuid, который обычно генерирует случайный uuid.

При тестировании вы сказали, что хотите, чтобы он всегда возвращал одно и то же значение.Для этого вы можете заменить unittest.mock.Mock на uuid.uuid4.

In [36]: uuid_mock = Mock(return_value=uuid.UUID('77f1df52-4b43-11e9-910f-b8ca3a9b9f3e'))

In [37]: uuid_mock()
Out[37]: UUID('77f1df52-4b43-11e9-910f-b8ca3a9b9f3e')

Примерно так: для тестирования следующей функции (f)

import uuid, unittest
from unittest.mock import Mock, patch

def f():
    z = uuid.uuid4()
    return z.int

Целью патча является метод uuid - uuid.uuid4.Укажите unittest.mock.Mock с фиксированным возвращаемым значением для параметра new, равного патч .Во время теста вместо Mock будет подставлено uuid.uuid4

class TestF(unittest.TestCase):

    uuid_mock = Mock(return_value=uuid.UUID('77f1df52-4b43-11e9-910f-b8ca3a9b9f3e'))

    good_uuid = uuid.UUID('77f1df52-4b43-11e9-910f-b8ca3a9b9f3e').int
    bad_uuid = uuid.UUID('77f1df52-4b43-11e9-910f-b8ca3a9b5a31').int

    @patch(target='uuid.uuid4', new=TestF.uuid_mock)
    def test_myFunction_True(self):
        self.assertEqual(f(), self.good_uuid)

    @patch(target='uuid.uuid4', new=TestF.uuid_mock)
    def test_myFunction_False(self):
        self.assertNotEqual(f(), self.bad_uuid)

if __name__ == '__main__':
    unittest.main()

Результат:

..
----------------------------------------------------------------------
Ran 2 tests in 0.001s

OK

Если вы хотите протестировать функцию, основанную на f 's возвращает значение, и вы хотите, чтобы f всегда возвращал одно и то же значение во время тестирования, затем сделайте f целью для патча .

def g():
    return f() == uuid.UUID('77f1df52-4b43-11e9-910f-b8ca3a9b9f3e').int

class TestG(unittest.TestCase):
    good_uuid_mock = Mock(return_value=uuid.UUID('77f1df52-4b43-11e9-910f-b8ca3a9b9f3e').int)
    bad_uuid_mock = Mock(return_value=uuid.UUID('77f1df52-4b43-11e9-910f-b8ca3a9b5a31').int)

    @patch(target='__main__.f', new=TestG.good_uuid_mock)
    def test_myFunction_True(self):
        self.assertTrue(g())
    @patch(target='__main__.f', new=TestG.bad_uuid_mock)
    def test_myFunction_False(self):
        self.assertFalse(g())
1 голос
/ 20 марта 2019

Это зависит от вашего импорта.Допустим, у вас есть модуль с именем module.py, и у вас есть импорт, подобный этому:

from uuid import uuid4

Это означает, что в этом модуле у нас теперь есть переменная с именем uuid4.Это вещь, чтобы высмеивать.

@patch('path.to.module.uuid4.int')
...