2016-09-22 104 views
0

我想設置os.listdir在UT中引發OSError,但它不會引發任何事情。Python MagicMock到os.listdir不會引發錯誤

我的代碼:

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') 

問題是什麼? (我不能正常使用模擬到os.listdir)

+0

get_list_of_files()是什麼樣子的?它如何使用'os.listdir()',你是否導入'os'或者你是否使用'from os import listdir'? –

+0

您不需要爲'self.mock_listdir.return_value'顯式創建'MagicMock'實例。這是*默認*。 –

+0

'get_list_of_files'使用'os.listdir'獲取列表,然後過濾它...不復雜 – tmsblgh

回答

1

您需要設置的副作用爲self.mock_listdir,不是的返回值:

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

畢竟,你要調用os.listdir()提高例外情況,不是調用返回值os.listdir()(您從不使用os.listdir()())。

演示(使用patch()作爲上下文管理器,它具有相同的效果,用它作爲裝飾):

>>> 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 

注意,設置self.mock_listdir模擬的side_effect將持續到其他測試!你應該使用一個新的補丁每個測試。您可以使用patch爲每個測試一個裝飾,使用的而不是使用每個測試用例補丁:

@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') 

如果你堅持使用您在setUp啓動一個補丁,你必須清除之後出現副作用(將其設置爲None)。

除此之外,沒有必要爲return_value明確創建MagicMock實例;那已經是默認的返回值了。您可以改爲存儲該默認值:

self.mock_listdir = self.listdir_patcher.start() 
self.mock_listdir_rv = self.mock_listdir.return_value 
相關問題