3

I am trying to write a pytest test for this function. It looks for folders named like a day.

from settings import SCHEDULE
from pathlib import Path
import os
import datetime

def get_schedule_dates():
    schedule_dates = []
    for dir in os.listdir(SCHEDULE):  # schedule is a path to a lot of directories
        if Path(SCHEDULE, dir).is_dir():
            try:
                _ = datetime.datetime.strptime(dir, '%Y-%m-%d')
                schedule_dates.append(dir)
            except ValueError:
                pass
    return schedule_dates

Mocking os.listdir works fine. (when I turn off the isdir check)

from mymod import mycode as asc
import mock


def test_get_schedule_dates():
    with mock.patch('os.listdir', return_value=['2019-09-15', 'temp']):
        result = asc.get_schedule_dates()
        assert '2019-09-15' in result
        assert 'temp' not in result

Mocking pathlib's Path at the same time doesn't work:

def test_get_schedule_dates():
    with (mock.patch('os.listdir', return_value=['2019-09-15', 'temp']),
          mock.patch('pathlib.Path.isdir', return_value=True)):
        result = asc.get_schedule_dates()
        assert '2019-09-15' in result
        assert 'temp' not in result

I get the error:

E             AttributeError: __enter__

How can I mock both listdir and Path in the same call?

576i
  • 7,579
  • 12
  • 55
  • 92

1 Answers1

3

It looks like I can only use one mock per with statement, testing this way works.

def test_get_schedule_dates():
    with mock.patch('os.listdir', return_value=['2019-09-15', 'temp']):
        with mock.patch('pathlib.Path.is_dir', return_value=True):
            result = asc.get_schedule_dates()
            assert '2019-09-15' in result
            assert 'temp' not in result
576i
  • 7,579
  • 12
  • 55
  • 92