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)
So how pass "handler" (a extra argument) to my_new_do_log?
if i try something like:
mock_do_log.side_effect = my_new_do_log(handler)
I lost arguments from my context manager (title and msg). Is it possible append extra arguments to context manager.
You can define a new callable in controller() and use it as side effect. The simple and neat way to do it is to use lambda function:
@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()
where my_new_do_log() signature become
def my_new_do_log(handler, *args, **kwargs):
....
You can either define a new explicit function to do it
@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()
But my taste is for the lambda version.
The question about context manager is little bit confused : you don't have any context manager in your example but just a patch decorator that behave like context manager. Anyway I think you can iterate my suggestion to take in account how many arguments you want.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With