2016-05-11 5 views
0

ich einen Komponententest für die folgende Funktion zu schreiben:Python: Zurückgeben Tupel für os.walk in Unittest

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) 

Dies ist, was ich im Moment haben:

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) 

aber ich behalte immer den Fehler:

for root, dirs, files in os.walk(path): 
ValueError: too many values to unpack 

oder wenn ich ändern es:

mock_os_walk.return_value = (['test1'],['test2'],['test3']) 

ich den Fehler:

ValueError: need more than 1 value to unpack 

Wohin gehe ich falsch?

Antwort

1

Ihre mock von os.walk eine iterable zurückgeben muss, da Sie for ... in os.walk(...): tun

Es stellt sich heraus, dass ein Tupel eine ist iterierbar. Wenn Sie also ...mock.return_value = (...) festlegen, definieren Sie das iterable, das zurückgegeben wird.

Sie rufen os.walk, und erhalten Sie ein Tupel zurück. Aber Sie nannten es im Rahmen einer for Schleife, so effektiv Sie geschrieben haben:

for a,b,c in ('test1', 'test2', 'test3'): 

Welche expandiert nach:

a,b,c = 'test1' 

das erste Mal durch die Schleife.

Was Sie wirklich wollen, ist eine Iterable, die einen Wert für jede der Variablen, mindestens einmal und möglicherweise mehr gibt. Dieser Code funktioniert, und ich denke, dass Sie den Rest herausfinden können:

#!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() 
1

Um das os.walk() Ergebnisformat anzupassen, benötigen Sie einen iterable haben, wo jedes Element aus 3 Elementen besteht - die root, dirs und files. Ersetzen:

mock_os_walk.return_value = ('test1','test2','test3') 

mit, zum Beispiel:

mock_os_walk.return_value = [('./test1', ['test2', 'test3'], ['test4.txt']), ]