組み込み関数を使っているメソッドの単体テストを行う
実ファイルを使わずにテストしたい場合、ファイルopenメソッドのスタブ(モック)を作ってテストします。
-
unittest
モジュールを使う -
mock_open
という便利なメソッドがある -
open
のような組み込み関数
のモックを作成する場合は、名前にbuiltins
を使い、builtins.open
のように書く -
mock_open(read_data='str1¥nstr2¥n')
のように、モックのファイルから読み出すデータを指定できる
サンプルコード
(テストしたいファイル。ファイルの読み書きを行っている)
# file_mock_sample.py
class FileMockSample:
def my_func_1(self):
path1 = '/tmp/not_exist_file_1.txt'
with open(path1, mode='r') as f1:
lines = f1.readlines()
print(lines) # ['line 1\n, 'line 2\n', 'line 3']
return lines
def my_func_2(self):
path2 = '/tmp/not_exist_file_2.txt'
with open(path2, mode='w') as f2:
f2.write('line1\n')
f2.write('line2\n')
f2.write('line3\n')
(テストコード。mock_openを使ってファイルのモックを作成してテストする)
# test_file_mock_sample.py
from unittest.mock import patch, mock_open
from file_mock_sample import FileMockSample
class TestFileMockSample:
def test_my_func_1(self):
dt = 'readline1\nreadline2\nreadline3\n'
mock_io = mock_open(read_data=dt)
# openは組み込み関数なので、「builtins」を使う
with patch('builtins.open', mock_io):
fm = FileMockSample()
result = fm.my_func_1()
mock_io.assert_called_once_with('/tmp/not_exist_file_1.txt', mode='r')
assert result == ['readline1\n', 'readline2\n', 'readline3\n']
def test_my_func_2(self):
mock_io = mock_open()
# openは組み込み関数なので、「builtins」を使う
with patch('builtins.open', mock_io):
fm = FileMockSample()
fm.my_func_2()
mock_io.assert_called_once_with('/tmp/not_exist_file_2.txt', mode='w')