在类和方法上组合 @mock.patch 时的顺序

sin*_*ned 8 python unit-testing python-unittest python-unittest.mock

当一个方法应该在测试用例中被模拟时,可以@mock.patch在 pythonunittest框架中应用装饰器(参见1):

    class MyTest(TestCase):
        @patch('method2')
        @patch('method1')
        def test_stuff(self, mock_method1, mock_method_2):
            ...
Run Code Online (Sandbox Code Playgroud)

根据文档2,也可以将 用作@mock.patch类装饰器:

    @patch('method2')
    @patch('method1')
    class MyTest(TestCase):
        def test_stuff(self, mock_method_1, mock_method_2):
            ...
Run Code Online (Sandbox Code Playgroud)

因此,将这两种方法结合起来也应该是可能且合理的:

    @patch('method1')
    class MyTest(TestCase):
        @patch('method2')
        def test_stuff(self, mock_method_A, mock_method_B):
            ...
Run Code Online (Sandbox Code Playgroud)

现在我想知道模拟按什么顺序传递给test_stuff. 那么mock_method_A嘲笑method1还是method2

sin*_*ned 7

方法装饰器中的模拟在类装饰器之前应用。Ie mock_method_A是模拟method2并且mock_method_B是模拟method1

请参阅这个独立的示例进行说明:

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()

Run Code Online (Sandbox Code Playgroud)