LoginSignup
1
3

More than 3 years have passed since last update.

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

Last updated at Posted at 2020-07-23

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

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

参考

1
3
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
3