Я хочу высмеять метод класса и использовать wraps
, так что он действительно вызван, но я могу проверить переданные ему аргументы. Я видел в нескольких местах (например, здесь), что обычный способ сделать это следующий (адаптированный, чтобы показать мою мысль):
from unittest import TestCase
from unittest.mock import patch
class Potato(object):
def foo(self, n):
return self.bar(n)
def bar(self, n):
return n + 2
class PotatoTest(TestCase):
spud = Potato()
@patch.object(Potato, 'foo', wraps=spud.foo)
def test_something(self, mock):
forty_two = self.spud.foo(n=40)
mock.assert_called_once_with(n=40)
self.assertEqual(forty_two, 42)
Тем не менее, это создает экземпляр класса Potato
, чтобы связать макет с методом экземпляра spud.foo
.
Мне нужно, чтобы издеваться над методом foo
во всех экземплярах Potato
и обернуть их вокруг оригинальных методов. Т.е. мне нужно следующее:
from unittest import TestCase
from unittest.mock import patch
class Potato(object):
def foo(self, n):
return self.bar(n)
def bar(self, n):
return n + 2
class PotatoTest(TestCase):
@patch.object(Potato, 'foo', wraps=Potato.foo)
def test_something(self, mock):
self.spud = Potato()
forty_two = self.spud.foo(n=40)
mock.assert_called_once_with(n=40)
self.assertEqual(forty_two, 42)
Это, конечно, не работает. Я получаю сообщение об ошибке:
TypeError: foo() missing 1 required positional argument: 'self'
Однако он работает, если wraps
не используются, поэтому проблема не в макете, а в том, как она вызывает завернутую функцию. Например, это работает (но, конечно, мне пришлось "подделать" возвращаемое значение, потому что теперь Potato.foo
никогда не запускается):
from unittest import TestCase
from unittest.mock import patch
class Potato(object):
def foo(self, n):
return self.bar(n)
def bar(self, n):
return n + 2
class PotatoTest(TestCase):
@patch.object(Potato, 'foo', return_value=42)#, wraps=Potato.foo)
def test_something(self, mock):
self.spud = Potato()
forty_two = self.spud.foo(n=40)
mock.assert_called_once_with(n=40)
self.assertEqual(forty_two, 42)
Это работает, но он не запускает исходную функцию, которую мне нужно запустить, потому что возвращаемое значение используется в другом месте (и я не могу подделать его из теста).
Это можно сделать?
Примечание. Фактическая причина моих потребностей заключается в том, что я тестирую приложение api для отдыха с веб-тестированием. Из тестов я выполняю некоторые запросы wsgi к некоторым путям, а моя среда создает некоторые классы и использует их методы для выполнения запроса. Я хочу, чтобы захватить параметры, отправленные на эти методы, чтобы сделать некоторые asserts
о них в моих тестах.