Пересмешивать многие, но не все функции в классе с помощью макета Python

Я пытаюсь проверить класс Python. Я хочу высмеять некоторые методы класса, но не все. Это может быть достигнуто достаточно хорошо с mock.patch, Моя проблема в том, что:

  1. Существует множество функций для исправления, так что это означает много вложенных вызовов для исправления.
  2. Существует много тестов, и из-за ограниченного характера патчей это означает, что мне нужно патчить каждый тест (есть много тестов для этого класса, которые нуждаются в одном и том же патче).

Есть ли чистое решение для этого?

Чтобы дать больше цвета, вот пример:

# test_me.py
class ClassUnderTest:

    # All foo functions should be mocked
    def foo1(self):
        pass

    def foo2(self):
        pass

    def foo3(self):
        pass                

    # All bar functions should NOT be mocked
    def bar1(self):
        pass

    def bar2(self):
        pass

    def bar3(self):
        pass                        


# test.py

@mock.patch.object(test_me.ClassUnderTest, 'foo3', autospec=True)
@mock.patch.object(test_me.ClassUnderTest, 'foo2', autospec=True)
@mock.patch.object(test_me.ClassUnderTest, 'foo1', autospec=True)
class MyTestCase(unittest.TestCase):

    def setup_mocks(self, mock_foo1, mock_foo2, mock_foo3):
        # Do things like assign side_effect or return_value to each of the foo mocks
        pass

    def test_1(self, mock_foo1, mock_foo2, mock_foo3):
        self.setup_mocks(mock_foo1, mock_foo2, mock_foo3)
        # Do test_1 tests

    def test_2(self, mock_foo1, mock_foo2, mock_foo3):
        self.setup_mocks(mock_foo1, mock_foo2, mock_foo3)        
        # Do test_2 tests

Это решение становится все менее чистым, чем больше классов и функций мне нужно высмеивать. Есть ли лучшее решение для этого?

Я готов принять ответ "вам нужно реорганизовать свой код, чтобы сделать его более тестируемым". Я привык проектировать тестирование в архитектуре из мира C/C++. Тем не менее, я надеялся на лучшее от динамического языка. Я давно использую python, но мне никогда не приходилось углубляться в насмешки.

1 ответ

Одна вещь, которая может вам помочь, это заглушить недопустимость класса в методе установки.

class ClassUnderTestStub(ClassUnderTest):
  def __init__(self, *args, **kwargs):
    self.arbitrary_attr = None
    ...

def setUp(self):
  self.helper = self.ClassUnderTestStub()
  self.helper.arbitrary_function = mock.MagicMock(...)

def testFoo(self):
  self.helper.foo_dependency = mock.MagicMock(...)
Другие вопросы по тегам