Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Order when combining @mock.patch on class and methods

When a method should be mocked within a test case it is possible to apply the @mock.patch decorator in the python unittest framework (see 1):

    class MyTest(TestCase):
        @patch('method2')
        @patch('method1')
        def test_stuff(self, mock_method1, mock_method_2):
            ...

According to the docs 2, it is also possible to apply the @mock.patch as a class decorator:

    @patch('method2')
    @patch('method1')
    class MyTest(TestCase):
        def test_stuff(self, mock_method_1, mock_method_2):
            ...

So it should also be possible and reasonable to combine these two approaches:

    @patch('method1')
    class MyTest(TestCase):
        @patch('method2')
        def test_stuff(self, mock_method_A, mock_method_B):
            ...

Now I was wondering in which order the mocks are passed to test_stuff. So does mock_method_A mock method1 or method2?

like image 942
sinned Avatar asked Jun 22 '26 14:06

sinned


1 Answers

The mocks from the method decorator are applied before the class decorator. I.e mock_method_A is the mock for method2 and mock_method_B is the mock for method1

See this self contained example for illustration:

from unittest import TestCase, main, mock


def method1():
    return 1


def method2():
    return 2


@mock.patch('test.method2', return_value='method2')
@mock.patch('test.method1', return_value='method1')
class TestClassDecoratorOrder(TestCase):
    def test_order(self, mock_method1, mock_method2):
        self.assertEqual(mock_method1(), 'method1')
        self.assertEqual(mock_method2(), 'method2')


class TestMethodDecoratorOrder(TestCase):
    @mock.patch('test.method2', return_value='method2')
    @mock.patch('test.method1', return_value='method1')
    def test_order(self, mock_method1, mock_method2):
        self.assertEqual(mock_method1(), 'method1')
        self.assertEqual(mock_method2(), 'method2')


@mock.patch('test.method2', return_value='method2')
class TestCombinedDecoratorOrder(TestCase):
    @mock.patch('test.method1', return_value='method1')
    def test_order(self, mock_method1, mock_method2):
        self.assertEqual(mock_method1(), 'method1')
        self.assertEqual(mock_method2(), 'method2')


if __name__ == "__main__":
    main()

like image 113
sinned Avatar answered Jun 25 '26 04:06

sinned



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!