Search code examples
pythonmockingmagicmock

How can I mock the return value of a function to be a string, then mock out the return value of an attribute of that function?


So I am working with the below basic function:

def whatever(..): 
    for input_file in files:
        compressed_file = Path(input_file)
    if not compressed_file.name.replace('test_', '').startswith(COMPRESSED_FILE_PREFIX):
        continue

So I mock the Path function like this:

@mock.patch('path_to_Path_function.Path')
def test_choose_MFII_files(mock_Path):
    mock_Path.return_value = 'files/exchange' 
    mock_Path.name.return_value = 'whatever'

Now when I run this, I get an error saying

AttributeError: 'str' object has no attribute 'name'

I can see why I get this error, because mock_Path.return_value is set to a string! But how can I set mockPath.name.return_value to whatever; I just want to mock it out.

I think using MagicMock() somehow would work but I'm not sure how. Any help would be great!


Solution

  • You want:

    @mock.patch('path_to_Path_function.Path')
    def test_choose_MFII_files(mock_Path):
        mock_Path.return_value.name = 'whatever'
        path_to_Path_function.whatever(...)
    

    mock_Path's return value (which defaults to another mock object) corresponds to compressed_file in the function under test, so the thing you want to set to a string is the name attribute of that object.

    If you wanted to write it a little more verbosely to make the nesting more obvious it might look like:

    @mock.patch('path_to_Path_function.Path')
    def test_choose_MFII_files(mock_path_cls):
        mock_path_obj = mock_path_cls()
        mock_path_obj.name = 'whatever'
        path_to_Path_function.whatever(...)