Python Mock - Mocking Several Open

After reading this: How do I make fun of the open used in instructions with (using the Python Mock structure)?

I can make fun of a public 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) 

This works well when my tested method used a single public statement. Here is my proven 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 (here "text1").

I would like to have "text1" for old text and "text2" for new text.

How can i do this?

+6
source share
2 answers

Here is a quick way to get what you want. It deceives a little, because the two file objects in the test method are the same object, and we just change the return value of the read call after each read. You can use the same technique in several layers if you want the file objects to be different, but it will be rather dirty and this may mask the intent of the test unnecessarily.

Replace this line:

  m_file.read.return_value = 'text1'

from:

  reads = ['text1', 'text2']
     m_file.read.side_effect = lambda: reads.pop (0)
+5
source

Perhaps a good possible solution is to simply write the code so that it can easily test it. In the case of "diff," this seems easy enough (not having a lot of other contexts, admittedly) to use diff as arguments to already-open file objects. This is probably a pretty small change in the code, and makes testing very simple, since you can easily provide mock file objects for diff () when you test it, instead of trying to jump over hoops, mocking two instances of the same the built-in function as a context manager, called inside ... itself ... or something; -)

 import StringIO diff(a, b): oldtext = a.read() newtext = b.read() def test_diff(): a = StringIO.StringIO('text1') b = StringIO.StringIO('text2') res = diff(a, b) <some assertion here> 

Will this work for your business?

+3
source

Source: https://habr.com/ru/post/908826/


All Articles