我正在为以下功能编写单元测试:
def create_zip(path,zipf):
#Create zip files
for root, dirs, files in os.walk(path):
for file in files:
#write all json files to a zip file
for name in glob.glob('*.json'):
os.chdir(root)
#write files to zip file
zipf.write(name)
#Remove files after creating zip file
os.remove(name)
这就是我现在所拥有的:
tmpfilepath = os.path.join(tempfile.gettempdir(), "tmp-testfile")
@mock.patch('my_script.os.walk')
def test_create_basic_zip(self,mock_os_walk):
mock_os_walk.return_value = ('test1','test2','test3')
zipf = zipfile.ZipFile(self.tmpfilepath, 'w', zipfile.ZIP_DEFLATED)
files = my_script.create_zip('.',zipf)
但是我一直收到错误:
for root, dirs, files in os.walk(path):
ValueError: too many values to unpack
或当我将其更改为:
mock_os_walk.return_value = (['test1'],['test2'],['test3'])
我收到错误:
ValueError: need more than 1 value to unpack
我哪里错了?
答案 0 :(得分:1)
为了匹配os.walk()
结果格式,您需要有一个iterable,其中每个项目由3个元素组成 - root
,dirs
和files
。替换:
mock_os_walk.return_value = ('test1','test2','test3')
,例如:
mock_os_walk.return_value = [('./test1', ['test2', 'test3'], ['test4.txt']), ]
答案 1 :(得分:1)
你的os.walk模拟需要返回一个iterable,因为你正在做for ... in os.walk(...):
事实证明,元组是可迭代的。因此,当您设置...mock.return_value = (...)
时,您将定义将返回的迭代。
你打电话给os.walk
,然后取回一个元组。但是你在for
循环的上下文中调用它,所以你写得很有效:
for a,b,c in ('test1', 'test2', 'test3'):
扩展为:
a,b,c = 'test1'
第一次通过循环。
你真正想要的是提供一个迭代,它给每个变量一个值,至少一次,甚至更多。这段代码有效,我想你可以弄清楚其余部分:
#!python3
from unittest import mock
import os
def other_function():
for a,b,c in os.walk('.'):
print(a,b,c)
@mock.patch('os.walk')
def test_code(mock_os_walk):
mock_os_walk.return_value = ((1,2,3), (4,5,6), (7,8,9))
other_function()
test_code()