如何在 python 中模拟并仍然允许执行模拟函数的实际代码
How to mock in python and still allow the actual code of mocked function to execute
我最近开始使用 python 中的 mock 框架。似乎如果我修补一个函数,则不会调用实际代码 - 这意味着数据库更改等未实现此实际函数所做的。
我一直在尝试通过事先调用函数并存储 return 值并将其作为 arg 传递给 patch() 来绕过它,但是
有更好的方法吗?理想情况下,我想要一个作为 silent observer
工作的代码,我可以简单地询问它是否调用了某个 observed
函数,调用了多少次,参数是什么
我当前的代码
return_val = funct()
# C: Now call me again and assert that these intensive computation functions are not called but taken from cache
with patch('funct', return_value=return_val) as mock_task:
me_response = self.client.get(me_url, format='json') #should fetch from cache
assert not mock_task.called
要模拟调用的方法,您应该使用 wraps
关键字。考虑以下因素:
class Foo(object):
def do_thing(self, a):
print("A: %s" % a)
self._do_private_thing(a)
def _do_private_thing(self, a):
print("PRIVATE STUFF HAPPENING.")
print("A: %s" % a)
然后在你的测试中你会得到类似的东西:
import mock
a = Foo()
with mock.patch.object(a, '_do_private_thing', wraps=a._do_private_thing) as private_mock:
a.do_thing("lol")
private_mock.assert_called_with("lol")
希望对您有所帮助。
您可以将 Mock#side_effect
属性设置为您的原始函数。
orig = funct
funct = Mock(side_effect=orig)
我确实觉得 loganasherjones 的回答更优雅。
只是为可能需要的人增加另一种可能性。
我最近开始使用 python 中的 mock 框架。似乎如果我修补一个函数,则不会调用实际代码 - 这意味着数据库更改等未实现此实际函数所做的。
我一直在尝试通过事先调用函数并存储 return 值并将其作为 arg 传递给 patch() 来绕过它,但是
有更好的方法吗?理想情况下,我想要一个作为 silent observer
工作的代码,我可以简单地询问它是否调用了某个 observed
函数,调用了多少次,参数是什么
我当前的代码
return_val = funct()
# C: Now call me again and assert that these intensive computation functions are not called but taken from cache
with patch('funct', return_value=return_val) as mock_task:
me_response = self.client.get(me_url, format='json') #should fetch from cache
assert not mock_task.called
要模拟调用的方法,您应该使用 wraps
关键字。考虑以下因素:
class Foo(object):
def do_thing(self, a):
print("A: %s" % a)
self._do_private_thing(a)
def _do_private_thing(self, a):
print("PRIVATE STUFF HAPPENING.")
print("A: %s" % a)
然后在你的测试中你会得到类似的东西:
import mock
a = Foo()
with mock.patch.object(a, '_do_private_thing', wraps=a._do_private_thing) as private_mock:
a.do_thing("lol")
private_mock.assert_called_with("lol")
希望对您有所帮助。
您可以将 Mock#side_effect
属性设置为您的原始函数。
orig = funct
funct = Mock(side_effect=orig)
我确实觉得 loganasherjones 的回答更优雅。
只是为可能需要的人增加另一种可能性。