returns 相同值作为参数传递的模拟方法

Mock method which returns same value passed as argument

如何使用 python unittest.mock 模拟 python 方法,它将 return 相同的值作为参数传递,

我试过了,

from unittest.mock import MagicMock

def dummy_function(value):
    "Will return same value as value passed to the function"
    return value

# To moke gettext function used in template
# Then I pass this mock method to Jinja2 template to moke gettext string
_ = MagicMock(return_value=dummy_function)

当我打印 jinja 模板时,它显示测试如下所示,

<div class="order_details">\n                
<legend class="badge">&lt;function dummy_function at 0x10887f730&gt;</legend>\n            
</div>\n 

原始 Jinja2 模板有

<div class="order_details">             
<legend class="badge">_('Details')</legend>           
</div>

return_value 只是一个 固定对象 到 return,你只是告诉模拟调用的结果是一个函数对象。

您想改用 side_effect attribute

_ = MagicMock(side_effect=dummy_function)

side_effect 设置为一个函数会导致它被调用 使用与 mock 相同的参数。见 documentation:

If you pass in a function it will be called with same arguments as the mock and unless the function returns the DEFAULT singleton the call to the mock will then return whatever the function returns.

演示:

>>> from unittest.mock import MagicMock
>>> identity = lambda a: a
>>> MagicMock(return_value=identity)('called')  # returns the function object, it won't call it
<function <lambda> at 0x10fa61620>
>>> MagicMock(side_effect=identity)('called')   # will call the function
'called'

您直接将函数对象作为 return 值传递,这就是它打印函数的 repr(名称和内存地址)的原因。您需要将您想要的实际值作为 return 传递,因此:

_ = MagicMock(return_value=dummy_function(somevalue))

但是如果函数总是return传递的值是没用的,创建一个模拟就足够了,所以可能只是这样做:

_ = MagicMock(return_value=somevalue)

然后按照您的意愿调用模拟。

旁注:_ 用法而不是名称的目的是什么?你在嘲笑 gettext 吗?如果没有或者给模拟一个名字会更清晰,最好的 IMO 是像你正在模拟的真实函数一样命名模拟以明确。