Thursday, 3 February 2022

How can I mock pathlib.Path.open and pathlib.path.unlink with the same syntax?

I use pathlib.Path.open() and pathlib.Path.unlink() in my productive code. The unittest for that work. But I use two different ways to patch(). One with @patch decorator and one with a context manager with mock.patch().

I would like to have @patch only like this.

class MyTest(unittest.TestCase):
    @mock.patch('pathlib.Path.unlink')
    @mock.patch('pathlib.Path.open')
    def test_foobar(self, mock_open, mock_unlink):

But the real code currenty looks like this

import unittest
from unittest import mock
import pathlib

class MyTest(unittest.TestCase):
    @mock.patch('pathlib.Path.unlink')
    def test_foobar(self, mock_unlink):
        # simulated CSV file
        opener = mock.mock_open(read_data='A;B\n1;2')

        with mock.patch('pathlib.Path.open', opener):
            result = validate_csv(file_path=pathlib.Path('foo.csv'))
            self.assertTrue(result)

Technical my problem here is that I do not know how to add my CSV content to mock_open when using the @patch decorator.

It could look like this:

class MyTest(unittest.TestCase):
    @mock.patch('pathlip.Path.open')
    @mock.patch('pathlib.Path.unlink')
    def test_foobar(self, mymock_unlink, mymock_open):
        # simulated CSV file
        opener = mock.mock_open(read_data='A;B\n1;2')

        # QUESTION: How do I bring 'opener' and 'mymock_open'
        # together now?

        result = validate_csv(file_path=pathlib.Path('foo.csv'))
        self.assertTrue(result)

But the goal of my question is to improve readability and maintainability of the code. Using two decorators would reduce the indention. Choosing one way (decorators or context managers) would IMHO be easier to read.



from How can I mock pathlib.Path.open and pathlib.path.unlink with the same syntax?

No comments:

Post a Comment