3

I have a method that does the following:

    import os

    ...

    if not os.path.exists(dirpath):
        os.makedirs(dirpath)

I'm trying to mock the makedirs and path.exists but when I do this with patch the mocks conflict:

@patch('os.makedirs')
@patch('os.path.exists')
def test_foo(self, makedirs, exists):
    c = Config()
    c.foo()

    assert makedirs.called
    assert exists.called

If I disable either makedirs or exists they both work fine but have an issue when being used together.

I've also tried using with patch('os.makedirs') as makedirs: syntax which doesn't change anything.

Does anyone know why they are conflicting or what I can do to resolve this?

Thanks!

1 Answer 1

3

If you mock os.path.exists as you do, it will return a mock, which always evaluates to True - so your code will never reach os.makedirs. To make this work, you have to provide a return value for the mock:

@patch('os.makedirs')
@patch('os.path.exists', return_value=False)
def test_foo(self, exists, makedirs):
    c = Config()
    c.foo()

    makedirs.assert_called_once()
    exists.assert_called_once()

Note also that the order of the mocks was reverted in your code - the argument for the last patch decorator has to go first.

I have also replaced assert xx.called with xx.assert_called_once() - the assert_called_... methods of Mock provide more fine-grained possibilities for checks.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.