在Python unittest框架中修改全局变量
我正在用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的输入?。