Je ne comprends pas pourquoi je ne peux pas me moquer de NamedTemporaryFile.name dans cet exemple:
from mock import Mock, patch
import unittest
import tempfile
def myfunc():
with tempfile.NamedTemporaryFile() as mytmp:
return mytmp.name
class TestMock(unittest.TestCase):
@patch('tempfile.NamedTemporaryFile')
def test_cm(self, mock_tmp):
mytmpname = 'abcde'
mock_tmp.__enter__.return_value.name = mytmpname
self.assertEqual(myfunc(), mytmpname)
Résultats des tests dans:
AssertionError: <MagicMock name='NamedTemporaryFile().__enter__().name' id='140275675011280'> != 'abcde'
Vous définissez la mauvaise maquette: mock_tmp
n'est pas le gestionnaire de contexte, mais plutôt renvoie un gestionnaire de contexte. Remplacez votre ligne de configuration par:
mock_tmp.return_value.__enter__.return_value.name = mytmpname
et votre test fonctionnera.
Voici une alternative avec pytest et fixateur moqueur , ce qui est également une pratique courante:
def test_myfunc(mocker):
mock_tempfile = mocker.MagicMock(name='tempfile')
mocker.patch(__+ '.tempfile', new=mock_tempfile)
mytmpname = 'abcde'
mock_tempfile.NamedTemporaryFile.return_value.__enter__.return_value.name = mytmpname
assert myfunc() == mytmpname