Reputation: 1083
Say I have a method that gets passed some paths, reads the files at each of these paths, then returns a dictionary from file name to file content, like so:
from contextlib import ExitStack
from pathlib import Path
class ClassToTest:
def method_to_test(self, *paths: Path):
with ExitStack() as stack:
files = [stack.enter_context(path.open(mode='r')) for path in paths]
return {f.name: f.read() for f in files}
Now say I want to test that if I pass in e.g. C:\wherever\file_name.xyz
that the returned dictionary contains the key file_name.xyz
. Since my method under test is opening and reading files, I want to mock out the Path object. I think I can do something like:
from unittest.mock import Mock, mock_open
class Tests:
def test(self):
mock_path = Mock(spec=Path)
mock_path.open = mock_open()
# ???
files = ClassToTest().method_to_test(mock_path)
assert 'file_name.xyz' in files
But I can't figure out how to get f.name
(i.e. mock_path.open().name
) to return file_name.xyz
.
Upvotes: 1
Views: 1653
Reputation: 40703
Try assert mock_path.open().name in files
. Should just work as you are using the mocking library. It'll be a fragile test though as mock_path.name != mock_path.open().name
If you're using pytest, then just use the tmp_path
fixture which is unique for each test invocation.
import pytest
def f(path):
with path.open() as f:
return {f.name: f.read()}
def test_f(tmp_path):
name = 'some_file.txt'
content = 'hello\nworld'
path = tmp_path / name
path.write_text(content)
result = f(path)
assert str(path) in result
assert content in result.values()
def test_g(tmp_path):
assert list(tmp_path.iterdir()) == []
Upvotes: 3