Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

python - Accessing objects mocked with patch

I've been using the mock library to do some of my testing. It's been great so far, but there are some things that I haven't completely understand yet.

mock provides a nice way of patching an entire method using patch, and I could access the patched object in a method like so:

@patch('package.module')
def test_foo(self, patched_obj):
    # ... call patched_obj here
    self.assertTrue(patched_obj.called)

My question is, how do I access a patched object, if I use the patch decorator on an entire class?

For example:

@patch('package.module')
class TestPackage(unittest.TestCase):

    def test_foo(self):
        # how to access the patched object?
like image 959
bow Avatar asked Feb 21 '23 02:02

bow


1 Answers

In this case, test_foo will have an extra argument, the same way as when you decorate the method. If your method is also patched, it those args will be added as well:

@patch.object(os, 'listdir')
class TestPackage(unittest.TestCase):
    @patch.object(sys, 'exit')
    def test_foo(self, sys_exit, os_listdir):
        os_listdir.return_value = ['file1', 'file2']
        # ... Test logic
        sys_exit.assert_called_with(1)

The arguments order is determined by the order of the decorators calls. The method decorator is called first, so it appends the first argument. The class decorator is outer, so it will add a second argument. The same applies when you attach several patch decorators to the same test method or class (i.e. the outer decorator goes last).

like image 57
bereal Avatar answered Feb 28 '23 02:02

bereal