The following is a simplification of a more complex problem, where I need to verify the contents of Excel files. I'd like to write unit tests for the functions I'll be needing, but ideally would like to mock these tests so I don't have to have a sample Excel sheet available.
The following function works:
functions_to_test.py:
import openpyxl
def read_excel_file_contents(filename: str, sheetname: str, cell: str) -> str:
wb = openpyxl.load_workbook(filename, read_only=True)
ws = wb[sheetname]
return ws[cell].value
test.py
import unittest
from unittest.mock import MagicMock, patch
import functions_to_test
class FunctionsToTest(unittest.TestCase):
@patch('functions_to_test.openpyxl')
def test_read_mocked_excel_file(self, openpyxl_mock):
wb = openpyxl_mock.workbook()
ws = openpyxl_mock.worksheet()
openpyxl_mock.load_workbook = MagicMock(return_value=wb)
wb.get_sheet_by_name = MagicMock(return_value=ws)
ws["A1"].value = "Some content"
self.assertEqual(
functions_to_test.read_excel_file_contents("a mocked excel file", sheetname="somesheet", cell="A1"),
"Some content"
)
if __name__ == "__main__":
unittest.main()
Output:
======================================================================
FAIL: test_read_mocked_excel_file (__main__.FunctionsToTest)
Assert the correct contents of reading a mocked Excel file
----------------------------------------------------------------------
Traceback (most recent call last):
File "C:\Users\markh\AppData\Local\Programs\Python\Python39\lib\unittest\mock.py", line 1337, in patched
return func(*newargs, **newkeywargs)
File "c:\Users\markh\Python\Testing\test.py", line 18, in test_read_mocked_excel_file
self.assertEqual(
AssertionError: <MagicMock name='openpyxl.workbook().__ge[45 chars]200'> != 'Some content'
----------------------------------------------------------------------
Ran 1 test in 0.003s
I believe I have to use MagicMock() for this, but can't seem to figure out how exactly. I've looked at Mocking Method Calls In Python, but my case seems to go one step further compared to the answers given in there.