2017-09-23 34 views
0

试图在Python 3.6中使用side_effect来模拟PermissionError异常。看起来像我的函数被调用,并提出EPERM异常,但它不能运行我的except语句。相同的代码按预期运行,出现'真正'的OSError异常。我的代码:Python - 嘲笑操作系统错误异常

#my_module.py 
import os 
import errno 
import sys 
import inspect 

def open_file(fname): 
    try: 
     with open('./' + fname, 'w') as f: 
      print('never get here') 
     return(0) 

    except PermissionError as e: 
     print('ERROR: \nIn function: ' + inspect.stack()[0][3]) 
     print('On line: {}'.format(sys.exc_info()[-1].tb_lineno), type(e).__name__, e) 
     sys.exit(1) 

我的测试:

#OpenFileMockTestCase.py 
from unittest import TestCase 
from unittest import mock 
import errno 
import my_module 

class OpenFileMockTestCase(TestCase): 

    @mock.patch('my_module.os.open') 
    def test_2_open_file_mock_oserror(self, mock_oserror): 
     with self.assertRaises(SystemExit): 
      mock_oserror.my_module.open_file.side_effect = (OSError((errno.EPERM), 'Not Allowed')) 
      print('starting open_file with testfile2.txt...') 
      mock_oserror.my_module.open_file('testfile2.txt') 

当我运行:

C:\Users\mylib>coverage3 run -m unittest OpenFileMockTestCase.py -v 
test_2_open_file_mock_oserror (OpenFileMockTestCase.OpenFileMockTestCase) ... starting open_file with testfile2.txt... 

ERROR 

====================================================================== 
ERROR: test_2_open_file_mock_oserror (OpenFileMockTestCase.OpenFileMockTestCase) 
---------------------------------------------------------------------- 
Traceback (most recent call last): 
    File "c:\users\xti027\appdata\local\programs\python\python36\lib\unittest\mock.py", line 1179, in patched 
    return func(*args, **keywargs) 
    File "C:\Users\xti027\Documents\DataTool-Git\DataTool\DataLoaderConfig\OpenFileMockTestCase.py", line 14, in test_2_open_file_mock_oserror 
    mock_oserror.my_module.open_file('testfile2.txt') 
    File "c:\users\xti027\appdata\local\programs\python\python36\lib\unittest\mock.py", line 939, in __call__ 
    return _mock_self._mock_call(*args, **kwargs) 
    File "c:\users\xti027\appdata\local\programs\python\python36\lib\unittest\mock.py", line 995, in _mock_call 
    raise effect 
PermissionError: [Errno 1] Not Allowed 

---------------------------------------------------------------------- 
Ran 1 test in 0.031s 

FAILED (errors=1) 

我已看过一些关于异常,以便问题和答复,并嘲笑像How do I write a unit test for OSError?看着Python的doc:https://docs.python.org/3.6/library/unittest.mock.html#module-unittest.mock 我是否在正确的地方嘲笑正确的项目?

回答

0

你可以只提高PermissionError例外:

mock_oserror.side_effect = PermissionError 

请注意,我们直接设置在嘲笑open()呼叫副作用!我还会模拟全球open()名称在您的模块测试中,而不是os.open

你也应该直接调用函数下测试,而不是你的mock_oserror对象的属性:

import my_module 

# .... 

@mock.patch('my_module.open') 
def test_2_open_file_mock_oserror(self, mock_open): 
    mock_open.side_effect = PermissionError 
    print('starting open_file with testfile2.txt...') 
    with self.assertRaises(SystemExit): 
     my_module.open_file('testfile2.txt') 

我使用的名称,而不是mock_open这里,为更好地反映了被嘲笑。

演示:

>>> import os 
>>> import errno 
>>> import sys 
>>> import inspect 
>>> from unittest import mock 
>>> def open_file(fname): 
...  try: 
...   with open('./' + fname, 'w') as f: 
...    print('never get here') 
...   return(0) 
...  except PermissionError as e: 
...   print('ERROR: \nIn function: ' + inspect.stack()[0][3]) 
...   print('On line: {}'.format(sys.exc_info()[-1].tb_lineno), type(e).__name__, e) 
...   sys.exit(1) 
... 
>>> with mock.patch('__main__.open') as mock_oserror: 
...  mock_oserror.side_effect = PermissionError 
...  try: 
...   open_file('testfile2.txt') 
...  except SystemExit: 
...   print('test passed, sys.exit() called') 
... 
ERROR: 
In function: open_file 
On line: 3 PermissionError 
test passed, sys.exit() called 
+0

完美的结果对我来说。感谢您的代码清理和解释清晰。 – BilboC