Python 如何为访问从csv文件创建的全局字典的函数编写单元测试?

Python 如何为访问从csv文件创建的全局字典的函数编写单元测试?,python,unit-testing,global-variables,Python,Unit Testing,Global Variables,我有一个process_persons()Python函数,它访问全局字典,如下所示: def process_persons(): for k, v in person_dict.items(): # do some processing def main(): global person_dict person_dict = {} reader = csv.reader(open('person_file.csv', 'r'

我有一个process_persons()Python函数,它访问全局字典,如下所示:

def process_persons():
    for k, v in person_dict.items():
        # do some processing

def main():

    global person_dict        
    person_dict = {}
    reader = csv.reader(open('person_file.csv', 'r'))
    for row in reader:
        key = (row[0], row[1])
        person_dict[key] = row[2]
我编写了如下的单元测试:

def test_process_persons(self):
    process_persons()
    # assert that the processing is done right!
但是我得到了一个错误:NameError:没有定义全局名称“person\u dict”。感谢您的帮助


请注意,我无法更改正在测试的方法的签名

我认为它实际上是没有定义的。请尝试用以下内容替换
global person\u dict

person_dict = {}
name错误:未定义全局名称“person\u dict”

那是因为你没有定义它。它怎么知道它是什么?你说
person\u dict[key]=row[2]
,但这并不自动使它成为字典。您必须用一个值初始化它,例如

person_dict = {}
上面说这是一本空字典


也不需要
全局
声明。您正在将其作为文件的顶层执行(即,不在函数或类中),以便可以正常使用。

不确切地确定您要实现的目标,但考虑到被测函数的签名已冻结,我可能会这样做

def process_persons():
    for k, v in person_dict.items():
        # do some processing

person_dict = {}
if __name__ == '__main__':
    reader = csv.reader(open('person_file.csv', 'r'))
    for row in reader:
        key = (row[0], row[1])
        person_dict[key] = row[2]
你需要在某个地方定义一个人。声明它是全局的并不能定义它<代码>全局用于指定在模块级从函数中定义的变量。如果未指定
global
,则将在函数中创建一个新的局部变量,该变量将隐藏全局变量。然后,当函数退出时,您新创建的变量将超出作用域,被垃圾收集,并被遗忘为无用


现在您已经在模块级别定义了person dict,您只需在调用
process\u persons
更改输入数据之前从测试代码中为其分配即可。

对我的代码进行了一些更改。用
def main()
替换
if uuuuu name\uuuuuuuu==''uuuuuuu main\uuuuuuuuu:
,并添加
person\u dict={}
@Malgi
def main
很好,但把
person\u dict={}
放在外面,就像托拜厄斯做的那样。放下
global
东西,你不需要它,这通常是不好的做法。Tobias的解决方案不起作用,因为当我们在单元测试
test\u process\u persons()内部调用
test\u process\u persons()
时,
person\u dict
是空的,CSV文件还没有存储在itAh中,我明白你在说什么了。那么,您是在测试中调用
main()
?在这种情况下,它可能不应该被称为
main
,而是
initialise\u person\u dict
或其他什么。或者根本不把它放在函数中,但如果uuu name uuu=='\uuuu main uuu'
也不要放在
下,因为这只会在直接运行模块时起作用。实际上,我实际的
main()
并没有那么简单。它有一些输入参数,用于指定
person\u文件的路径。因此,如果我把它放在函数中或从测试中调用“main()”,我应该知道这些参数并将它们传递给该函数或
main()
。我想除了删除全局字典
person\u dict
,并将
process\u persons()
更改为'process\u persons(person\u dict)':/对我的代码进行了一些更改之外,没有其他方法了。用
def main():
替换了
if uuuuuuu name\uuuuuuuuu==''uuuuuuuu main:
,并添加了
person\u dict={}
。感谢您的回答。我对代码做了一些更改。如果使用
def main():
替换
\uuu name\uuuuuuu==''uuuuuuu main\uuuuuu':
,并添加了
person\u dict={}
。您现在怎么想?您的解决方案不起作用,因为当我们在单元测试中调用
process\u persons()
test\u process\u persons()
person\u dict
是空的,CSV文件还没有存储在其中。我想这一切都取决于您想要测试什么。是
流程中的功能
,还是
main中的功能
,还是两者兼而有之?要查看新的
main
函数从
process\u persons
读取的数据,您必须将
person\u dict
的声明移动到模块级别。否则它将无法从
流程人员访问。现在,通过测试,您可以首先调用
main
,然后调用
process\u persons