単体テストで少し外に出ることは容易に認めます。 私はテストに合格していますが、私の解決策は洗練されていないと感じています。インポートされたモジュールでPython Unittestでファイルをモックする
テストされているクラス:
class Config():
def __init__(self):
config_parser = ConfigParser()
try:
self._read_config_file(config_parser)
except FileNotFoundError as e:
pass
self.token = config_parser.get('Tokens', 'Token',)
@staticmethod
def _read_config_file(config):
if not config.read(os.path.abspath(os.path.join(BASE_DIR, ROOT_DIR, CONFIG_FILE))):
raise FileNotFoundError(f'File {CONFIG_FILE} not found at path {BASE_DIR}{ROOT_DIR}')
醜いテスト:
class TestConfiguration(unittest.TestCase):
@mock.patch('config.os.path.abspath')
def test_config_init_sets_token(self, mockFilePath: mock.MagicMock):
with open('mock_file.ini', 'w') as file: #here's where it gets ugly
file.write('[Tokens]\nToken: token')
mockFilePath.return_value = 'mock_file.ini'
config = Config()
self.assertEqual(config.token, 'token')
os.remove('mock_file.ini') #quite ugly
は編集:私は何を意味することは、私はファイルを作成する代わりに、のいずれかをからかっていました。 誰もがファイルオブジェクトをmock
する方法を知っていますが、そのデータセットはASCIIテキストを読み込むように設定されていますか?クラスは深く埋まっています。 それ以外は、でデータを設定する方法はConfigParser
です。確かに、テストは "うまくいく"、うまくやっていない。他のテストの行動について尋ねたものについては
が、ここでは、このクラスでは別のテストの例です:
@mock.patch('config.os.path.abspath')
def test_warning_when_file_not_found(self, mockFilePath: mock.MagicMock):
mockFilePath.return_value = 'mock_no_file.ini'
with self.assertRaises(FileNotFoundError):
config.Config._read_config_file(ConfigParser())
はお時間をいただき、ありがとうございます。
これは不合理ではないようです。別の解決策として 'Config()'インスタンスをインスタンス化する前に 'BASE_DIR'、' ROOT_DIR'、 'CONFIG_FILE'をモジュールで設定することができませんでしたか?あなたの 'Config'クラスがオプションのパラメータとして設定ファイルへのパスを受け入れるなら、どうでしょうか? – larsks
私はあなたが 'ConfigParser'をテストするべきではないと思います。 '_read_config_file'は、それが何を意味するのか、設定ファイルを読み込み、それができないときに例外を送出することをテストするべきです。 –
ありがとう、@larsks。私はそのユーティリティも参照していますが、今は、私の設定に関連するすべての情報を1つの場所に保存することに興味があります(つまり、 '.ini'ファイルの名前を' .ini'ファイル)。本当に私に迷惑をかけているのは、 'ConfigParser'クラスが' .read'を呼び出すときにファイル情報を設定する方法です。むしろ、アスキー文字を使ってデータを設定する嘲笑されたファイルオブジェクトにパッチを当てたいのですが、クラスが設計されている方法はそれを直感的にするものではありません。 self.assertRaisesと '(FileNotFoundError)::' ' config.Config._read_config_file(config.ConfigParser())' を - –