Python: Mocking a context manager

I don't understand why I can't mock NamedTemporaryFile.name in this example:

    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)

Test results in:

    AssertionError: <MagicMock name='NamedTemporaryFile().__enter__().name' id='140275675011280'> != 'abcde'

You are setting the wrong mock: mock_tmp is not the context manager, but instead returns a context manager. Replace your setup line with:

    mock_tmp.return_value.__enter__.return_value.name = mytmpname

and your test will work.

From: stackoverflow.com/q/28850070