【问题标题】:Is it possible to write a function-level pytest fixture that applies a mock decorator to the function?是否可以编写一个函数级的 pytest 夹具,将模拟装饰器应用于函数?
【发布时间】:2019-11-06 14:08:37
【问题描述】:

在我们的 repo 中,我们有一些对 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

这可能吗?

【问题讨论】:

    标签: python mocking pytest decorator fixtures


    【解决方案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)
    

    【讨论】:

    • 这是pytest的方式;因此,您应该接受自己的答案。此外,夹具主体可以更简单:with mock.patch.object(S3Hook, 'write_to_s3'): yield 已经足够了。
    【解决方案2】:

    在写这些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

    【讨论】:

    • 谢谢,这是对当前代码的增量改进,因为开发人员只需记住每个类编写一次代码。然而,我真的在寻找一个项目级的解决方案,这样开发人员就不会忘记在一类新的测试代码上执行此操作。这就是为什么我更喜欢在我的原始示例中使用带有autouse=True 的全局pytest 固定装置。
    • 你也可以看看这里:stackoverflow.com/questions/47312835/…
    • 啊!没关系,我看到我可以在全局 pytest 夹具中使用修补程序。这似乎有效,谢谢!
    猜你喜欢
    • 1970-01-01
    • 2020-11-22
    • 1970-01-01
    • 1970-01-01
    • 2021-04-19
    • 1970-01-01
    • 1970-01-01
    • 2013-11-17
    相关资源
    最近更新 更多