I have a class SQLES in a separate script, sqles.py, which is imported in main.py and comprises methods to read SQL data and set the results in the class instance.
I am now writing a test script, test_main.py, in which I want to define a mock SQLES class to be used transparently by main.py instead of the real SQLES. I am not testing SQLES itself, and the idea of the mock class is to include the same set of methods but return hard-coded lists of data rows.
I have searched for hours, but not one result on python/mock/etc explains how to set up this apparently very simple requirement. This is the test script (truncated for clarity) which I have prepared so far:
import unittest.mock
import main # main.py script I wish to run with the mocked SQLES class
class MockSQLES: # Dummy class I wish main.py to instantiate and use instead of SQLES
def __init__(self):
return
def init(self, logger, cmd_args_record, cmd_args_playback):
return
# Couple of specimen methods, to give an idea of what dummy SQL class does ..
def get_exchange_rates(self):
self.exchange_rates['GBP'] = [
[ '2021-09-13', 0.722298 ],
[ '2021-08-20', 0.734203 ]
]
return
def get_firms_names_other(self):
self.firms_names_other[firm_id] = [
[ 131, 'Acme Industries' ],
[ 132, 'Acme Research' ]
]
return
::::
with unittest.mock.patch('main.SQLES') as MockSQLES:
main.main()
But when I try running it, a debug print after the instance assigment:
sql = SQLES()
shows that the resulting sql object has type unittest.mock.MagicMock rather than the MockSQLES I expected, and sure enough the methods in the latter are not being called.
So in summary, I would like to know how to fix this. Perhaps Mock is the wrong approach, and some other method (monkey patching? ) is better suited for this.
Also, I don't wish to tinker with the main.py script any more than can be avoided. (It's obvious how a mock SQL class could be used if main.py had a test flag or similar to create an instance of either SQLES or MockSQLES.)