web-dev-qa-db-ja.com

Python unittest frameworkでグローバル変数を変更する

私はPythonで一連の単体テストに取り組んでおり、その一部は構成変数の値に依存しています。これらの変数はグローバルPython configファイルに保存され、他のモジュールで使用されます。設定変数の異なる値の単体テストを書きたいのですが、まだこれを行う方法が見つかりません。

私がテストしているメソッドの署名を書き換える可能性はありません。

これは私が達成したいことです:

from my_module import my_function_with_global_var

class TestSomething(self.unittest):

    def test_first_case(self):
         from config import MY_CONFIG_VARIABLE
         MY_CONFIG_VARIABLE = True
         self.assertEqual(my_function_with_global_var(), "First result")

    def test_second_case(self):
         from config import MY_CONFIG_VARIABLE
         MY_CONFIG_VARIABLE = False
         self.assertEqual(my_function_with_global_var(), "Second result")

ありがとう。

編集:サンプルコードをより明確にしました。

36
badzil

@ Flimm's answer のようにunittest.mock.patchを使用します(使用可能な場合)。


元の回答

これをしないでください:

from my_module import my_function_with_global_var

しかしこれは:

import my_module

そして、テスト対象のシステムを次のように変更せずに、インポートしたMY_CONFIG_VARIABLEmy_moduleを挿入できます。

class TestSomething(unittest.TestCase): # Fixed that for you!

    def test_first_case(self):
         my_module.MY_CONFIG_VARIABLE = True
         self.assertEqual(my_module.my_function_with_global_var(), "First result")

    def test_second_case(self):
         my_module.MY_CONFIG_VARIABLE = False
         self.assertEqual(my_module.my_function_with_global_var(), "Second result")

私の答えpyunitのstdinへの入力をどのようにシミュレートできますか? で似たようなことをしました。

47
Johnsyweb

代わりに、これらのグローバル変数をモックしたいでしょう。これの利点は、完了後にグローバルがリセットされることです。 Pythonには、これを可能にするモッキングモジュールが付属しています。

unittest.mock.patch デコレータとして使用されます:

class TestSomething(self.unittest):

    @patch('config.MY_CONFIG_VARIABLE', True)
    def test_first_case(self):
         self.assertEqual(my_function_with_global_var(), "First result")

コンテキストマネージャーとして使用することもできます。

    def test_first_case(self):
        with patch('config.MY_CONFIG_VARIABLE', True):
            self.assertEqual(my_function_with_global_var(), "First result")
65
Flimm

インポートのコードMY_CONFIG_VARIABLEをローカルスコープに追加し、すぐに別のオブジェクトで名前を上書きします。 configモジュールの値は変更されません。試して

import config
config.MY_CONFIG_VARIABLE = False

代わりに。

2
Sven Marnach