Пересмешивать многие, но не все функции в классе с помощью макета Python
Я пытаюсь проверить класс Python. Я хочу высмеять некоторые методы класса, но не все. Это может быть достигнуто достаточно хорошо с mock.patch
, Моя проблема в том, что:
- Существует множество функций для исправления, так что это означает много вложенных вызовов для исправления.
- Существует много тестов, и из-за ограниченного характера патчей это означает, что мне нужно патчить каждый тест (есть много тестов для этого класса, которые нуждаются в одном и том же патче).
Есть ли чистое решение для этого?
Чтобы дать больше цвета, вот пример:
# 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(...)