Python: Mocking a context manager

前端 未结 3 608
广开言路
广开言路 2020-11-30 01:30

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():
           


        
相关标签:
3条回答
  • 2020-11-30 02:12

    Extending Peter K's answer using pytest and the mocker fixture.

    def myfunc():
        with tempfile.NamedTemporaryFile(prefix='fileprefix') as fh:
            return fh.name
    
    
    def test_myfunc(mocker):
        mocker.patch('tempfile.NamedTemporaryFile').return_value.__enter__.return_value.name = 'tempfilename'
        assert myfunc() == 'tempfilename'
    
    0 讨论(0)
  • 2020-11-30 02:19

    Here is an alternative with pytest and mocker fixture, which is a common practice as well:

    def test_myfunc(mocker):
        mock_tempfile = mocker.MagicMock(name='tempfile')
        mocker.patch(__name__ + '.tempfile', new=mock_tempfile)
        mytmpname = 'abcde'
        mock_tempfile.NamedTemporaryFile.return_value.__enter__.return_value.name = mytmpname
        assert myfunc() == mytmpname
    
    0 讨论(0)
  • 2020-11-30 02:24

    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.

    0 讨论(0)
提交回复
热议问题