Reputation: 3056
Suppose I have the following function and I need to unit test it:
def move_files_to(files, path):
for file in files:
os.rename(file, path + "/" + file)
my thoughts on this topic:
Mocking os.rename would lead to no outcome, on the other hand, having files and renaming them would be "doing I/O" which should be avoided in unit tests. Please correct me, if I am wrong. Does testing make sense here?
Upvotes: 2
Views: 2090
Reputation: 20163
My recommendation would be
create a DirectoryTestCase(unittest.TestCase)
with
_tests
under tests/
) ii) creates an empty directory and iii) copies (test) files to it.Second, create the tests under that test case. You can test moving to same directory (rename), to a new directory (under the test directory, should it create if it does not exist or fail?) move a symlink, etc., all under the encapsulation of the existing directory.
If you want tests to run in parallel, give the directory a unique (random but valid) name.
Example code:
import unittest
import shutil
import os
import string
import random
class DirectoryTestCase(unittest.TestCase):
test_files = ['file.txt']
def setUp(self) -> None:
unique_string = ''.join(random.choices(string.digits, k=10))
self.path = os.path.join(os.path.dirname(__file__), '_temp' + unique_string)
shutil.rmtree(self.path, ignore_errors=True)
os.makedirs(self.path, exist_ok=True)
for file in self.test_files:
shutil.copy(file, self.path)
def tearDown(self) -> None:
shutil.rmtree(self.path, ignore_errors=True)
def test_basic(self):
# validate the existence of the file, not an actual test.
self.assertTrue(os.path.exists(os.path.join(self.path, 'file.txt')))
Upvotes: 3
Reputation: 311
There is no need to test os.rename
, but your code needs to be tested. In your particular case the simplest way is to patch os.rename
:
from unittest.mock import patch
def test_move_files():
files = ['a.txt', 'b.txt']
path = 'old'
expected = [(('a.txt', 'old/a.txt'),),
(('b.txt', 'old/b.txt'),)]
with patch('os.rename') as rename:
move_files_to(files, path)
assert rename.call_args_list == expected
Upvotes: 6
Reputation: 1785
since it is a difficulty to mock OS module in python, you can ignore to write unitest
But unit test means to validate your single method with some possible scenarios, so if you think that must validate all time. then a unit test is a must.
Upvotes: 0