モジュールに初期化されていないグローバル変数があり、アプリケーションの起動時に正しく初期化されます。型チェックには、python >= 3.6 の値を使用せずに構文を使用するvar: Type
ため、デフォルト値 ( になりますNone
) の型チェックを複雑にする必要はありません。
ここで、このグローバル変数を使用する別の関数を単体テストしたいのですが、からエラーが発生しunittest.mock.patch
ます。これが私がやっていることの簡略化されたバージョンです:
- ファイル mod.py:
global_var: bool
#global_var: bool = False
def init(val: bool) -> None:
global global_var
global_var = val
def do_stuff() -> str:
return "a" if global_var else "b"
- ファイル test.py:
import unittest.mock, mod
class MockUninitializedGlobal(unittest.TestCase):
def test_it(self):
with unittest.mock.patch("mod.global_var", True):
actual = mod.do_stuff()
expected = "a"
self.assertEqual(expected, actual)
- で実行し
python3 -m unittest test.py
ます。
例外は
Traceback (most recent call last):
File "/home/luc/soquestion/test.py", line 4, in test_it
with mock.patch("mod.global_var", True):
File "/nix/store/vs4vj1yzqj1bkcqkf3b6sxm6jfy1gb4j-python3-3.7.7/lib/python3.7/unittest/mock.py", line 1323, in __enter__
original, local = self.get_original()
File "/nix/store/vs4vj1yzqj1bkcqkf3b6sxm6jfy1gb4j-python3-3.7.7/lib/python3.7/unittest/mock.py", line 1297, in get_original
"%s does not have the attribute %r" % (target, name)
AttributeError: <module 'mod' from '/home/luc/soquestion/mod.py'> does not have the attribute 'global_var'
mod.py の 1 行目をコメントし、2 行目をコメント解除すると、テストはパスします。
アプリケーション コードでグローバル変数のデフォルト値を定義せずにテストに合格する方法はありますか?
編集:コメントに記載されているように、実際の変数は、テスト中にロードしたくない解析済みの構成ファイルです。これはコマンド ライン アプリケーションで使用されるため、変数は常にコマンド ラインの解析が完了した後に設定されます。実際のコードはhereとhereです。実際のテストでは、グローバル変数を bool として直接モックしようとしているのではなく、config オブジェクトのいくつかの属性をモックしようとしています。