Pythonの組み込み関数openのモックを作って単体テストする

組み込み関数を使っているメソッドの単体テストを行う

実ファイルを使わずにテストしたい場合、ファイル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')

参考

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です