Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python Mock - Mocking several open

After reading this : How do I mock an open used in a with statement (using the Mock framework in Python)?

I'm able to mock the open function in python using :

with patch(open_name, create=True) as mock_open:
    mock_open.return_value = MagicMock(spec=file)
    m_file = mock_open.return_value.__enter__.return_value
    m_file.read.return_value = 'text1'

    diffman = Diffman()
    diffman.diff(path1, path2)

It works well when my tested method used one open statement. Here is my tested method :

def diff(self, a, b):
    with open(a, 'r') as old:
        with open(b, 'r') as new:
            oldtext = old.read()
            newtext = new.read()

The values of oldtext and newtext are the same ('text1' here).

I would like to have 'text1' for the oldtext and 'text2' for the newtext.

How can I do this ?

like image 867
Sandro Munda Avatar asked Feb 19 '12 12:02

Sandro Munda


1 Answers

Here's a quick way of getting what you want. It cheats a little bit because the two file objects in the method under test are the same object and we're just changing the return value of the read call after each read. You can use the same technique in multiple layers if you want the file objects to be different, but it will be quite messy and it may disguise the intent of the test unnecessarily.

Replace this line:

    m_file.read.return_value = 'text1'

with:

    reads = ['text1', 'text2']
    m_file.read.side_effect = lambda: reads.pop(0)
like image 60
Glenn Avatar answered Sep 17 '22 23:09

Glenn