У меня есть класс, который мне нужно исправить, который работает подобно этомуподклассы MagicMock в питоне
class Foo(object):
def __init__(self, query):
self._query = query
def do_stuff(self):
# do stuff with self._query
Как бы я создал класс насмешливого для Foo таким образом, что
foo = MockFoo(query)
foo.do_stuff()
возвращает mock result, но все же принимая во внимание данные, переданные для query
. Я думал о подклассов MagicMock
как этот
class MockFoo(MagicMock):
def __init__(self, query, *args, **kwargs):
super(MagicMock, self).__init__(*args, **kwargs)
self._query
def do_stuff(self):
mock_result = self._query * 10
return MagicMock(return_value=mock_result)
, но я не могу вполне понять, как применить patch
использовать MockFoo
вместо MagicMock
в реальной TestCase. Мне нужно написать тест, подобный этому.
with patch('x.Foo') as mock_foo:
# run test code
self.assertTrue(mock_foo.called)
self.assertEqual(mock_foo.wait.return_value, 20)
Я знаю, что я могу просто использовать простой MagicMock
с autospec=True
или что-то и переопределить возвращаемые значения для каждого из методов, но было бы неплохо иметь макет класс, который я могу просто использовать, чтобы заменить класс производства за один присест. Ключевым битом является доступ к переменной-члену self._query
в методах макета, при этом он инициализируется в конструкторе (как и производственный класс).
Я не думаю, что это работает, потому что на каком-то уровне вам нужно различать реальные методы/свойства и издевавшиеся методы/свойства. Такие вещи, как «called» и «return_value», являются частью макета, поэтому не представляется возможным добавить их в модифицированный экземпляр производственного класса. Я думаю, что лучше делать то, что вы сказали, насмехаясь над тем, что вам нужно, и, возможно, добавьте вспомогательный код для этого. –