Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to mock python's read()

I'm trying to test the read() method in the following class:

class Channel(sam.Sam):
  def __open(self):
    try:
      self.__channel = open('%s/channel.ini' % os.path.dirname(os.path.realpath(__file__)), 'r+')
    except Exception as e:
      traceback.print_exc(file = sys.stdout)
      raise e

  def read(self):
    try:
      self.__open()
      return JSONEncoder().encode({
        "status": True,
        "channel": self.__channel.read().strip()
      })
    except Exception as e:
      traceback.print_exc(file = sys.stdout)
      return JSONEncoder().encode({
        "status": False
      })
    finally:
      self.__close()

As I understand it, I should be mocking the file.read() method (in self.__channel.read(), or maybe the os.open() method, but none of the examples I've found have the call to os.open() or file.read() deep inside a class.

I already tried __builtin__.read = MagicMock(return_value="something"), and many variations thereof, but not one of them even make sense. I'm kind of lost as to how to even start this.

Is this even the right way?

like image 296
Rodrigo Dagnese Avatar asked Dec 10 '25 10:12

Rodrigo Dagnese


1 Answers

Mock the open function; you can use the mock_open() utility function to provide a suitable mock:

from unittest.mock import mock_open

with patch('your_module.open', mock_open(read_data=JSON_TEST_DATA), create=True) as m:
    result = Channel().read()
    assert m.assert_called_once_with(expected_file_name)

The patch() call creates a new global open object in your your_module namespace, so when the Channel.__open() method runs it'll find that object rather than the open() built-in function.

By passing in a read_data argument to mock_open(), you can dictate what is returned by the self.__channel.read() call.

like image 198
Martijn Pieters Avatar answered Dec 12 '25 23:12

Martijn Pieters



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!