1

I'm writing unit tests with Python for a project and recently encountered a problem with the decorator @patch. I have the following method which I need to test

def _read_from_disk(self, excel_kwargs):
        """
        Read excel file from disk and apply excel_kwargs.

        Args:
            excel_kwargs: Parameters for pandas.read_excel.

        Returns:
            DataFrame or dict of DataFrames.
        """
        return pd.read_excel(self.location, **excel_kwargs)

My test method structure is

 @patch("program.data.excel.BaseExcelReader._read_from_disk.pd.read_excel")
    def test___read_from_disk(self, mock_df):
        mock_df.return_value = pd.DataFrame({"test_id": [1, 2, 3, 4, 5]})
        return_df = self.test_reader._read_from_disk(self.excel_kwargs_svd)
        pd.testing.assert_frame_equal(return_df, pd.DataFrame({"test_id": [1, 2, 3, 4, 5]}))

Which give me the following error:

ModuleNotFoundError: No module named 'program.data.excel.BaseExcelReader';
                       'program.data.excel' is not a package

Please note that the test method is only an example. The purpose of the question is to find a way to mock pandas.read_excel with @patch.

martineau
  • 119,623
  • 25
  • 170
  • 301
  • So your filename is `program/data/excel.py` or something else? As is, the patch is certainly wrong, as it tries to patch `pd` defined in the function - I would guess it is imported in the module. Please show the filename/structure of the tested code and the related imports. – MrBean Bremen May 05 '20 at 06:04
  • The import of pandas is "import pandas as pd" and file structure is as the one in the patch decorator "program.data.excel.BaseExcelReader._read_from_disk" . I was not able to find an example of how to mock pandas with @patch. – running_dog May 05 '20 at 06:31
  • The file name is program/data/excel.py – running_dog May 05 '20 at 06:32
  • It worked with @patch("program.data.excel.pd.read_excel") . Thank you. You made me think about the paths inside the file. – running_dog May 05 '20 at 06:42
  • Ah, this is what I thought - glad I could help! – MrBean Bremen May 05 '20 at 07:11

1 Answers1

2

You can directly patch the "pandas.read_excel" instead of "program.data.excel.BaseExcelReader._read_from_disk.pd.read_excel"

Code:

@patch("pandas.read_excel")
def test___read_from_disk(self, mock_df):
    mock_df.return_value = pd.DataFrame({"test_id": [1, 2, 3, 4, 5]})
    return_df = self.test_reader._read_from_disk(self.excel_kwargs_svd)
    pd.testing.assert_frame_equal(return_df, pd.DataFrame({"test_id": [1, 2, 3, 4, 5]}))