2016-09-22 3 views
0

Ich möchte os.listdir OSError in UT zu erhöhen, aber es nichts erhöhen.Python MagicMock zu os.listdir nicht Fehler melden

Mein Code:

def get_list_of_files(path): 
    try: 
     list_of_files = sorted([filename for filename in 
           os.listdir(path) if 
           filename.startswith('FILE')]) 

    except OSError as error: 
    raise Exception(error) 

    return list_of_files 

def setUp(self): 
    self.listdir_patcher = patch('os.listdir') 
    self.mock_listdir = self.listdir_patcher.start() 
    self.mock_listdir_rv = MagicMock() 
    self.mock_listdir.return_value = self.mock_listdir_rv 

def tearDown(self): 
    self.listdir_patcher.stop() 
def test(self): 
    e = OSError('abc') 
    self.mock_listdir_rv.side_effect = e 
    with self.assertRaises(OSError): 
     get_list_of_files('path') 

Was ist das Problem? (I nicht normal Mock zu os.listdir verwenden)

+0

Was 'get_list_of_files tut()' aussehen? Wie benutzt man 'os.listdir()', hast du 'os' importiert oder benutzt' os import listdir'? –

+0

Sie müssen nicht explizit eine 'MagicMock'-Instanz für' self.mock_listdir.return_value' erstellen. Das ist der * Standard *. –

+0

'get_list_of_files' benutze 'os.listdir', um eine Liste zu erhalten und dann zu filtern ... nicht kompliziert – tmsblgh

Antwort

1

Sie müssen den Nebeneffekt für self.mock_listdir setzen, nicht Rückgabewert ist:

def test(self): 
    e = OSError('abc') 
    self.mock_listdir.side_effect = e 
    with self.assertRaises(OSError): 
     get_list_of_files('path') 

Schließlich wollen Sie den Anruf os.listdir() zu erhöhen die Ausnahme, nicht der Aufruf an den Rückgabewert von os.listdir() (Sie verwenden nie os.listdir()()).

Demo (mit patch() als Kontext-Manager, der die gleichen Wirkungen wie mit ihm als Dekorateur hat):

>>> from unittest.mock import patch 
>>> import os 
>>> with patch('os.listdir') as mock_listdir: 
...  mock_listdir.side_effect = OSError('abc') 
...  os.listdir('path') 
... 
Traceback (most recent call last): 
    File "<stdin>", line 3, in <module> 
    File "/Users/mjpieters/Development/Library/buildout.python/parts/opt/lib/python3.6/unittest/mock.py", line 930, in __call__ 
    return _mock_self._mock_call(*args, **kwargs) 
    File "/Users/mjpieters/Development/Library/buildout.python/parts/opt/lib/python3.6/unittest/mock.py", line 986, in _mock_call 
    raise effect 
OSError: abc 

Beachten Sie, dass die side_effect der self.mock_listdir Mock Einstellung zu anderen Tests bestehen bleiben wird! Sie sollten wirklich einen neuen Patch pro Test verwenden. Sie können patch als Dekorateur bei jedem Test durchzuführen, verwenden Sie stattdessen eine pro-Testfall Patcher verwenden:

@patch('os.listdir') 
def test(self, mock_listdir): 
    e = OSError('abc') 
    mock_listdir.side_effect = e 
    with self.assertRaises(OSError): 
     get_list_of_files('path') 

Wenn Sie einen Patcher verwenden Sie in der setUp beginnen halten Sie, würden Sie das klären müssen Nebeneffekt danach (setze es auf None).

Abgesehen von all dem ist es nicht notwendig, die MagicMock Instanz für eine return_value explizit zu erstellen; das ist der Standard-Rückgabewert bereits. Sie könnten stattdessen, dass die Standard speichern:

self.mock_listdir = self.listdir_patcher.start() 
self.mock_listdir_rv = self.mock_listdir.return_value 
Verwandte Themen