You must use side_effect
attribute of your patched open
object (mock_open
) and don't forget to set the return_value
for __exit__
method.
@patch('__builtin__.open', spec=open)
def test_interface_mapping(self, mock_open):
handle1 = MagicMock()
handle1.__enter__.return_value.__iter__.return_value = ('aa', 'bb')
handle1.__exit__.return_value=False
handle2 = MagicMock()
handle2.__enter__.return_value.__iter__.return_value = ('AA', 'BB')
handle2.__exit__.return_value=False
mock_open.side_effect = (handle1, handle2)
with open("ppp") as f:
self.assertListEqual(["aa","bb"],[x for x in f])
with open("ppp") as f:
self.assertListEqual(["AA","BB"],[x for x in f])
[EDIT]
I found a much more elegant way to do it Mock builtin 'open" function when used in contextlib
So you can rewrote test like
@patch('__builtin__.open', new_callable=mock_open, read_data="aa
bb")
def test_interface_mapping_new(self, mo):
handlers = (mo.return_value,mock_open(read_data="AA
BB").return_value,)
mo.side_effect = handlers
with open("ppp") as f:
self.assertEqual("aa
bb",f.read())
with open("ppp") as f:
self.assertEqual("AA
BB",f.read())
And from python 3.4 you can use also readline(), readlines() without mocking anything else.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…