Search code examples
pythonunit-testingmockingpatch

Patching in unit tests does not work, actual method is being called


I have a python file : update_baseline_manifest.py. Now, I am writing unit tests and want to patch read_file and write_file and I have done it like

def update_baseline_manifest(baseline_manifest_path, vbf_info_map, logger):
    """ Updates manifest as per the part numbers in the vbfs_map """
    try:
        manifest_contents = read_file(baseline_manifest_path)
        // Do something


        write_file(manifest_contents, baseline_manifest_path)

def read_file(file_path):
    print('called read')
    with open(file_path, 'r') as file:
        return yaml.safe_load(file)


def write_file(contents, file_path):
    print('called write')
    with open(file_path, 'w') as file:
        yaml.dump(contents, file)

The test file looks like

from a.b.update_baseline_manifest import update_baseline_manifest

def test_update_baseline_manifest(self):
    test_contents = 'sample contents'

    with patch('update_baseline_manifest.read_file', return_value=test_contents) as \
        mock_read, patch('update_baseline_manifest.write_file') as mock_write:
        result = update_baseline_manifest(self.args.baseline_manifest_path,
                                            self.args.vbf_info_map,
                                            self.args.logger)

    mock_read.assert_called_with(self.args.baseline_manifest_path)
    mock_write.assert_called_with(contents_written, self.args.baseline_manifest_path)
    self.assertEqual(result, 0)

Now I can see the prints I added so it means the actual function was called and the mocked one wasn't. How do I patch them correctly so my mocked function gets called and not the actual one after importing the file at the top? I read a lot of posts about it but I cant get my head around it.


Solution

  • You need to provide full path of the function you want to mock. Refer to: https://docs.python.org/3/library/unittest.mock.html#where-to-patch

        ...
        with patch('a.b.update_baseline_manifest.read_file', return_value=test_contents) as \
    mock_read, patch('a.b.update_baseline_manifest.write_file') as mock_write:
        ...