2017-09-23 52 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