動機:
我希望能夠測驗一個場景,其中我的函式無法打開某個檔案進行寫入(實際上是追加,但我認為這無關緊要)并且我希望能夠將這種情況與“檔案不存在”區分開來“ 一。
例子:
import os
from stat import S_IREAD, S_IRGRP, S_IROTH
from typing import Optional
from tempfile import TemporaryDirectory
import unittest
DEFAULT_VAL = 100
def myfunc(fname: str) -> Optional[int]:
if not os.path.isfile(fname):
return DEFAULT_VAL
try:
with open(fname, 'at') as f:
return f.write('bar')
except IOError as e:
return None
class TestMyFunc(unittest.TestCase):
def test_read_file_when_ok(self):
with TemporaryDirectory() as tmpdir:
fn = os.path.join(tmpdir, 'foo.txt')
with open(fn, 'wt') as f:
f.write('')
self.assertEqual(myfunc(fn), 3)
def test_default_when_file_does_not_exist(self):
with TemporaryDirectory() as tmpdir:
fn = os.path.join(tmpdir, 'foo.txt')
self.assertEqual(myfunc(fn), DEFAULT_VAL)
def test_None_when_fails(self):
with TemporaryDirectory() as tmpdir:
fn = os.path.join(tmpdir, 'foo.txt')
with open(fn, 'wt') as f:
f.write('')
os.chmod(fn, S_IREAD | S_IRGRP | S_IROTH) # make it read only
self.assertIsNone(myfunc(fn))
if __name__ == '__main__':
unittest.main()
如您所見,我正在通過將檔案設定為只讀來測驗這一點,這 非常好:
$ python3 a.py
...
----------------------------------------------------------------------
Ran 3 tests in 0.001s
OK
..直到它在 bitbucket 上失敗,因為在docker中,管道在root.
并且root打開只讀檔案進行寫入沒有問題:
$ sudo python3 a.py
F..
======================================================================
FAIL: test_None_when_fails (__main__.TestMyFunc)
----------------------------------------------------------------------
Traceback (most recent call last):
File "a.py", line 36, in test_None_when_fails
self.assertIsNone(myfunc(fn))
AssertionError: 3 is not None
----------------------------------------------------------------------
Ran 3 tests in 0.001s
FAILED (failures=1)
我的后備解決方案:
I know I can refactor my code (which is unfortunatelly much larger than myfunc example) to accept some "file opener" where I can inject some mock which would raise appropriate exception, but I would very much prefer solution which does not require refactoring existing code and which could be isolated in the test.
This is my fallback if there's no other simple (and clean, no monkey-patching) solution.
What I'm looking/hoping for:
I sort-of feel/hope there may be some simple solution based on modifying the file or directory properties..
Question:
Is there a simpler way to simulate "can't open file for writing" so it:
- would work even for root
- would be distinguishable from "file not found"
- would work on linux (i.e. I don't need to support any other platform than Linux)
?
(GNU/Linux Debian 10, python3)
uj5u.com熱心網友回復:
你可以嘲笑open自己:
def test_None_when_fails(self):
with TemporaryDirectory() as tmpdir:
fn = os.path.join(tmpdir, 'foo.txt')
with open(fn, 'wt') as f:
f.write('')
m = unittest.mock.mock_open()
m.side_effect = PermissionError()
with unittest.mock.patch('__main__.open', m):
self.assertIsNone(myfunc(fn))
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/384441.html
