Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I patch mock multiple calls from os in python?

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!

like image 968
MysteriousWaffle Avatar asked Feb 15 '26 05:02

MysteriousWaffle


1 Answers

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.

like image 134
MrBean Bremen Avatar answered Feb 16 '26 18:02

MrBean Bremen



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!