2017-09-23 4 views
0

side_effect를 사용하여 Python 3.6에서 PermissionError 예외를 조롱하려고합니다. 내 함수가 호출되고 EPERM 예외가 발생했지만 내 except 문을 실행하지 못하는 것 같습니다. 동일한 코드가 '실제'OSError 예외에 대해 예상대로 실행됩니다. 내 코드 :Python - Mocking OS Error 예외

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

나는 실행하면 : 나는 예외에 여러 개의 SO 질문과 응답을 읽고 같은 How do I write a unit test for OSError?을 조롱하고 파이썬에서 보았다

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) 

doc : https://docs.python.org/3.6/library/unittest.mock.html#module-unittest.mock 올바른 장소에서 올바른 항목을 조롱하고 있습니까?

답변

0

당신은 방금 PermissionError 예외를 발생시킬 수 있습니다 : 우리는 조롱 open() 전화에 직접 부작용을 설정

mock_oserror.side_effect = PermissionError 

참고! 또한 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