mac*_*acm 2 mocking python-3.x
from unittest.mock import patch
def get_title():
return 'title'
def get_msg():
return 'msg'
def do_log(title, msg):
sys.stderr.write(get_title(),
get_msg())
return
def myfunction():
title = get_title()
msg = get_msg()
do_log(title, msg)
def my_new_do_log(*args, **kwargs):
'''
we know, args = title, msg
But I want add EXTRA arguments,
like handler (from caller / from controller)
'''
sys.stderr.write(get_title(),
get_msg(),
handler.get_author_from_handler()
)
# Note: handler is argument from controller!
@patch('do_log')
def controller(handler, mock_do_log):
mock_do_log.side_effect = my_new_do_log
myfunction()
if __name__ == '__main__':
controller(handler)
Run Code Online (Sandbox Code Playgroud)
那么如何将“处理程序”(一个额外的参数)传递给 my_new_do_log 呢?
如果我尝试类似的事情:
mock_do_log.side_effect = my_new_do_log(handler)
Run Code Online (Sandbox Code Playgroud)
我失去了上下文管理器的参数(标题和味精)。是否可以将额外的参数附加到上下文管理器。
您可以定义一个新的可调用对象controller()并将其用作副作用。简单而简洁的方法是使用lambda函数:
@patch('do_log')
def controller(handler, mock_do_log):
mock_do_log.side_effect = lambda *args,**kwargs:my_new_do_log(handler,*args,**kwargs)
myfunction()
Run Code Online (Sandbox Code Playgroud)
其中,my_new_do_log()签名成为
def my_new_do_log(handler, *args, **kwargs):
....
Run Code Online (Sandbox Code Playgroud)
您可以定义一个新的显式函数来执行此操作
@patch('do_log')
def controller(handler, mock_do_log):
def handler_log(*args,**kwargs):
my_new_do_log(handler,*args,**kwargs)
mock_do_log.side_effect = handler_log
myfunction()
Run Code Online (Sandbox Code Playgroud)
但我的口味是lambda版本。
关于上下文管理器的问题有点困惑:您的示例中没有任何上下文管理器,而只有一个行为类似于上下文管理器的补丁装饰器。无论如何,我认为您可以重复我的建议以考虑您想要的参数数量。