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

时间:2011-06-07 16:10:19

标签: python unit-testing global-variables

我正在使用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 个答案:

答案 0 :(得分:62)

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

答案 1 :(得分:45)

@Flimm's answer中那样使用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")

我在my answer to How can I simulate input to stdin for pyunit?中做了类似的事情。

答案 2 :(得分:2)

您将MY_CONFIG_VARIABLE导入到本地作用域中,然后立即使用其他对象覆盖该名称。这不会改变config模块中的值。尝试

import config
config.MY_CONFIG_VARIABLE = False

代替。