Подтвердить что ты не робот

Как вы издеваетесь над патчем класса python и получаете новый объект Mock для каждого экземпляра?

OK,
Я знаю, что это упоминается в руководстве и, вероятно, связано с side_effect и/или return_value, но простой, прямой пример поможет мне безмерно.

У меня есть:

class ClassToPatch():
   def __init__(self, *args):
       _do_some_init_stuff()

   def some_func():
       _do_stuff()


class UUT():
    def __init__(self, *args)
       resource_1 = ClassToPatch()
       resource_2 = ClassToPatch()

Теперь я хочу unit test класс UUT и высмеять ClassToPatch. Знание класса UUT будет создавать экземпляры только двух объектов ClassToPatch, я хочу, чтобы оболочка Mock возвращала новый объект Mock для каждого экземпляра, поэтому я могу позже утверждать вызовы по отдельности.

Как достичь этого, используя декоратор @patch в тестовом примере? А именно, как исправить следующий пример кода?

class TestCase1(unittest.TestCase):

    @patch('classToPatch.ClassToPatch',autospec=True)
    def test_1(self,mock1,mock2):
        _assert_stuff()
4b9b3361

Ответ 1

Вот вам быстрый 'грязный пример для вас:

import mock
import unittest

class ClassToPatch():
   def __init__(self, *args):
       pass

   def some_func(self):
       return id(self)

class UUT():
    def __init__(self, *args):
        resource_1 = ClassToPatch()
        resource_2 = ClassToPatch()
        self.test_property = (resource_1.some_func(), resource_2.some_func())

class TestCase1(unittest.TestCase):
    @mock.patch('__main__.ClassToPatch', autospec = True)
    def test_1(self, mock1):
        ctpMocks = [mock.Mock(), mock.Mock()]
        ctpMocks[0].some_func.return_value = "funky"
        ctpMocks[1].some_func.return_value = "monkey"
        mock1.side_effect = ctpMocks

        u = UUT()
        self.assertEqual(u.test_property, ("funky", "monkey"))

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

Я добавил test_property в UUT, чтобы unit test сделал что-то полезное. Теперь без макета test_property должен быть кортеж, содержащий идентификаторы двух экземпляров ClassToPatch. Но с макером это должен быть кортеж: ("funky", "monkey").

Я использовал свойство side_effect макетного объекта, чтобы на каждый вызов в инициализаторе UUT возвращался другой экземпляр ClassToPatch.

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

Изменить: О, кстати, когда я запускаю unit test, я получаю:

.
----------------------------------------------------------------------
Ran 1 test in 0.004s

OK