Python MagicMock到os.listdir不会引发错误

问题描述:

我想设置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

您需要设置的副作用为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