Python - 模拟操作系统错误异常

时间:2017-09-23 14:52:13

标签: python unit-testing exception mocking

尝试使用side_effect在Python 3.6中模拟PermissionError异常。看起来我的函数被调用并且引发了EPERM异常,但是它无法运行我的except语句。对于“真正的”OSError异常,相同的代码按预期运行。我的代码:

Dara.map(person => console.log(person.name))

我的测试:

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

我已经阅读了几个关于异常和类似How do I write a unit test for OSError?的嘲笑的SO问题和回答,并查看了Python文档:https://docs.python.org/3.6/library/unittest.mock.html#module-unittest.mock 我在正确的地方嘲笑合适的物品吗?

1 个答案:

答案 0 :(得分:1)

您只需提出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