Oliver
Oliver

Reputation: 60

How to mock filesystem partial in Python3

I want to mock a a filesystemcall that is creating an file. But I got the problem, that I am using flask to create the output and flask also needs to read the teamplate from filesystem. So I am running in an error while rendering the output with flask. Is there a good way to mock just one file instead of all filesystem calls?

def func_to_test(self, data_for_html):
    template_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), 'templates'))
    app = flask.Flask('my app', template_folder=template_dir)
    with app.app_context():
        rendered = render_template('index.html', data=data_for_html)
    with open(self.fileName, **self.options_file) as html_file:
        html_file.write(rendered)

def test_func(self, data):
     fake_file_path = "fake/file/path/filename"
     m = mock_open()
     with patch('builtins.open', mock_open()) as m:
        data_writer = FlaskObject(fileName=fake_file_path)
        data_writer.write(data)

Upvotes: 0

Views: 291

Answers (2)

bruno desthuilliers
bruno desthuilliers

Reputation: 77942

Split the function to test so you can test each part in isolation:

def _generate_content(self, data):
    template_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), 'templates'))
    app = flask.Flask('my app', template_folder=template_dir)
    with app.app_context():
        return render_template('index.html', data=data_for_html)

def _write_content(self, content):
    with open(self.fileName, **self.options_file) as html_file:
        html_file.write(content)



def func_to_test(self, data_for_html):
    rendered = self._generate_content(data_for_html)
    self._write_content(rendered)

and then you can mock those two methods and test that func_to_test calls them both with expected values.

Upvotes: 1

Iain Shelvington
Iain Shelvington

Reputation: 32304

Instead of mocking open you could create a temporary file that you write to instead using tempfile.

def test_func(self, data):
    with tempfile.NamedTemporaryFile() as f:
       data_writer = FlaskObject(fileName=f.name)
       data_writer.write(data)

This will not work on windows, if you wish for it to work on windows you would have to create the temp file with delete=False, close the file and then delete the file after the test

Upvotes: 1

Related Questions