Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What do @mock.patch decorators do in Python when there are more than the number of parameters of the decorated method/function?

For example:

@patch('my.project.trading.getEnrichedTradeData', lambda: TEST_TRADE_DATA)
@patch('my.project.subledger.getSubledgerData', getTestSubledgerData)
@patch('my.project.metadata.getSubledgerCodes', return_value=TEST_CODES)
@patch('my.project.reports.storeReport')
def test(self, storeReport):
    buildReport()
    storeReport.assert_called_with(EXPECTED_REPORT)
def buildReport():
    trades = getEnrichedTradeData()
    subledger = getSubledgerData()
    codes = getSubledgerCodes()
    report = Report(trades, subledger, codes)
    storeReport(report)

I thought that @patch passes its return value as an argument, so that's what will happen with the bottom-most decorator. What about the other 3? Disclaimer: Fairly green in python speak. Proficient in Java and C++. Please be as detailed as possible...

like image 820
Martin F Avatar asked Sep 20 '25 18:09

Martin F


1 Answers

Excerpt from the documentation of unittest.mock.patch:

If new is omitted, then the target is replaced with an AsyncMock if the patched object is an async function or a MagicMock otherwise. If patch() is used as a decorator and new is omitted, the created mock is passed in as an extra argument to the decorated function.

Since in your case, all of the 3 top patch decorators are called with the new argument, the 3 target objects would simply be replaced with the objects from the new argument, and the bottom patch decorator, without a new argument, would replace the target object with a MagicMock instance and pass it in as the extra argument storeReport to your test function.

like image 97
blhsing Avatar answered Sep 22 '25 09:09

blhsing