是否可以编写将模拟装饰器应用于函数的函数级pytest固定装置?

时间:2019-06-24 18:36:03

标签: python mocking pytest decorator fixtures

在我们的仓库中,我们有一些对s3的调用。我们从不希望它们在测试期间执行,因此我们在每个单独的测试中都将它们模拟出来,这很烦人。这是很多重复的代码,如果开发人员在运行测试之前忘记编写模拟,可能会很危险。

我想编写一个pytest固定装置,将模拟自动应用于每个测试功能。也就是说,我要更改代码,如下所示:

test_file.py:

@mock.patch.object(S3Hook, 'write_to_s3')
def test1(_):
    # test some stuff without writing to s3

@mock.patch.object(S3Hook, 'write_to_s3')
def test2(_):
    # test some more stuff without writing to s3

对此:

conftest.py:

@pytest.fixture(scope='function', autouse=True)
def mock_out_s3(request):
    # somehow apply the mock.patch.object decorator to request.function here


test_file.py:

def test1():
    # test some stuff; the mock is automatically applied, so we won't write to s3

def test2():
    # ditto

这可能吗?

2 个答案:

答案 0 :(得分:1)

在编写这些Unittests时。您可以这样做:


Class TestClass(TestCase):

    @classmethod
    def setUpTestData(cls):
        pass

    def tearDown(self):
        self.patcher.stop()

    def setup(self):
       self.patcher = mock.patch(S3Hook, 'write_to_s3')
       mock_apply = self.patcher.start()

    def test1(self):
    # test some stuff; the mock is automatically applied, so we won't write to s3

    def test2(self):
    # ditto


您可以在此处找到有关修补程序的更多详细信息:https://docs.python.org/3/library/unittest.mock.html#the-patchers

答案 1 :(得分:1)

发布有关如何使它工作的详细信息(基于ParthS007的回答),以帮助将来尝试做同一件事的其他任何人:

@pytest.fixture(scope='function', autouse=True)
def mock_out_s3(request):
    patcher = mock.patch.object(S3Hook, 'write_to_s3')
    patcher.start()
    request.addfinalizer(patcher.stop)