在Python unittest框架中修改全局变量

56 投票
3 回答
62215 浏览
提问于 2025-04-16 19:06

我正在用Python写一系列单元测试,其中一些测试需要依赖一个配置变量的值。这些变量存储在一个全局的Python配置文件里,并且在其他模块中也会用到。我想为不同的配置变量值写单元测试,但还没有找到合适的方法。

我无法修改我正在测试的方法的参数。

我想要实现的目标是:

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")

谢谢。

编辑:我把示例代码写得更清楚了。

3 个回答

2

你在代码中把 MY_CONFIG_VARIABLE 导入到本地环境里,然后立刻用一个不同的对象覆盖了这个名字。这样做并不会改变 config 模块里的值。你可以试试下面的代码:

import config
config.MY_CONFIG_VARIABLE = False

来看看效果。

84

你可能想要模拟那些全局变量。这样做的好处是,当你完成后,这些全局变量会被重置。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")
62

如果你能用的话,可以像@Flimm的回答那样使用unittest.mock.patch


原始回答

不要这样做:

from my_module import my_function_with_global_var

而是这样做:

import my_module

然后你可以把MY_CONFIG_VARIABLE注入到导入的my_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的输入?

撰写回答