Home > OS >  How to mock a function which makes a mutation on an argument that is necessary for the caller fuctio
How to mock a function which makes a mutation on an argument that is necessary for the caller fuctio

Time:12-04

I want to be able to mock a function that mutates an argument, and that it's mutation is relevant in order for the code to continue executing correctly.

Consider the following code:

def mutate_my_dict(mutable_dict):
    if os.path.exists("a.txt"):
        mutable_dict["new_key"] = "new_value"
        return True


def function_under_test():
    my_dict = {"key": "value"}
    if mutate_my_dict(my_dict):
        return my_dict["new_key"]
    return "No Key"


def test_function_under_test():
    with patch("stack_over_flow.mutate_my_dict") as mutate_my_dict_mock:
        mutate_my_dict_mock.return_value = True
        result = function_under_test()
    assert result == "new_value"

**Please understand i know i can just mock os.path.exists in this case but this is just an example. I intentionally want to mock the function and not the external module. **

I also read the docs here: https://docs.python.org/3/library/unittest.mock-examples.html#coping-with-mutable-arguments But it doesn't seem to fit in my case.

This is the test i've written so far, but it obviously doesn't work since the key changes:

def test_function_under_test():
    with patch("stack_over_flow.mutate_my_dict") as mutate_my_dict_mock:
        mutate_my_dict_mock.return_value = True
        result = function_under_test()
    assert result == "new_value"

Thanks in advance for all of your time :)

CodePudding user response:

With the help of Peter i managed to come up with this final test:

def mock_mutate_my_dict(my_dict):
    my_dict["new_key"] = "new_value"
    return True


def test_function_under_test():
    with patch("stack_over_flow.mutate_my_dict") as mutate_my_dict_mock:
        mutate_my_dict_mock.side_effect = mock_mutate_my_dict
        result = function_under_test()
    assert result == "new_value"

How it works is that with a side effect you can run a function instead of the intended function. In this function you need to both change all of the mutating arguments and return the value returned.

  • Related