open_repeatedly.py
import time
def open_repeatedly(path, retries=5, retry_interval=1.0):
while True:
try:
return open(path)
except OSError:
if retries <= 0:
raise
if retry_interval > 0:
time.sleep(retry_interval)
retries -= 1
Je ne sais pas trop pour quoi l'utiliser, mais si vous avez une fonction comme celle-ci, j'aimerais tester son comportement exceptionnel. Par exemple, si retry_interval
vaut 0, `` time.sleep () '' ne sera pas appelé.
Cependant, il est gênant de DI ```open () et
time.sleep () . L'interface se salit. Je veux aussi éviter les
** kwargs ''.
Donc, on m'a dit sur Twitter «unittest.mock.patch».
test.py
import os
from tempfile import mkstemp
import unittest
from unittest.mock import call, patch, MagicMock
import open_repeatedly
class TestOpenRepeatedly(unittest.TestCase):
def test_1(self):
with patch('open_repeatedly.open') as mock:
expected_ret = MagicMock()
mock.return_value = expected_ret
path = '/path/to/test.txt'
f = open_repeatedly.open_repeatedly(path)
self.assertEqual(f, expected_ret)
mock.assert_called_with(path)
def test_2(self):
path = '/path/to/test.txt'
with patch('open_repeatedly.open') as o_mock:
o_mock.side_effect = OSError('Test')
with patch('open_repeatedly.time.sleep') as s_mock:
calls = [call(1.0)] * 5
with self.assertRaises(OSError):
open_repeatedly.open_repeatedly(path)
self.assertEqual(5, s_mock.call_count)
s_mock.assert_has_calls(calls)
self.assertEqual(6, o_mock.call_count)
o_mock.assert_called_with(path)
def test_3(self):
path = '/path/to/test.txt'
with patch('open_repeatedly.open') as o_mock:
o_mock.side_effect = OSError('Test')
with patch('open_repeatedly.time.sleep') as s_mock:
with self.assertRaises(OSError):
open_repeatedly.open_repeatedly(
path, retry_interval=0)
self.assertEqual(0, s_mock.call_count)
self.assertEqual(6, o_mock.call_count)
o_mock.assert_called_with(path)
@patch('open_repeatedly.time.sleep')
@patch('open_repeatedly.open')
def test_4(self, o_mock, s_mock):
path = '/path/to/test.txt'
o_mock.side_effect = OSError('Test')
with self.assertRaises(OSError):
open_repeatedly.open_repeatedly(
path, retries=0)
self.assertEqual(0, s_mock.call_count)
self.assertEqual(1, o_mock.call_count)
o_mock.assert_called_with(path)
if __name__ == '__main__':
unittest.main()
Les décorateurs sont plus faciles.
$ python -m unittest
....
----------------------------------------------------------------------
Ran 4 tests in 0.005s
OK
Sentir que je l'ai implémenté Il semble que cela fonctionne comme prévu. Est-ce correct pour savoir comment l'utiliser?