【问题标题】:Pytest: How to call the patch of a fixturePytest:如何调用夹具的补丁
【发布时间】:2020-10-29 03:04:09
【问题描述】:

pytest 5.0.1 蟒蛇3.6

假设你有一个类,你在另一个类中导入和初始化

from file import Client
class A()

    def __init__(self):
        self.client = Client()

    def call(self):
        self.client.execute()

现在当我想测试它时,因为这个导入类涉及外部组件(例如数据库),我想模拟这件事的发生(例如,我不敢相信你读数据库这么慢......)。但实事求是。所以我有一个带有补丁的夹具。耶!

 @pytest.fixture
 def setup_a(self):
    with patch('path_to_patch') as patched:
        a = A()
    return a

但是,我似乎无法从 fxiture 中取出补丁来使用它。我尝试创建一个新补丁,但这不起作用(例如断言 False)

@patch('path_to_patch')
def test_successful_execution(self, new_patch, setup_a):
    setup_a.call()
    assert new_patch.execute.called

我也尝试过隐式使用上述补丁

@patch('path_to_patch')
def test_successful_execution(self, new_patch, setup_a):
    setup_a.call()
    assert setup_a.execute.called    

这样做的正确方法是什么?如果您需要更多解释,请告诉我。

【问题讨论】:

    标签: python-3.x mocking pytest patch fixtures


    【解决方案1】:

    我假设您想在A 中修补Client.execute,并且夹具应返回带有该修补程序的A 类型的对象。首先要确保补丁仍然处于活动状态:

     @pytest.fixture
     def mocked_a(self):
         with patch('path_to_a.Client.execute'):
             yield A()
    

    在您的示例中,您在修补范围之后返回了对象,这意味着修补已经在该点结束。另请注意,您必须修补在a 模块中导入的Client 模块(假设这是定义A 的位置)。

    要使用修补的对象,您现在可以:

    def test_successful_execution(mocked_a):
        mocked_a.call()
        mocked_a.Client.execute.assert_called_once()
    

    请注意,您可以像模拟它一样访问模拟。

    或者,您可以在夹具中返回模拟本身:

     @pytest.fixture
     def mocked_execute(self):
         with patch('path_to_a.Client.execute') as patched:
             yield patched
    
    def test_successful_execution(mocked_execute):
        a = A()
        a.call()
        mocked_execute.assert_called_once()
    

    在我看来,通过这种方式,您可以在测试中明确创建对象,并且测试更加清晰。

    (这不是我的想法,所以可能有错误......)

    【讨论】:

      猜你喜欢
      • 2023-01-03
      • 1970-01-01
      • 2021-03-26
      • 2018-10-07
      • 2020-01-15
      • 1970-01-01
      • 2023-01-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多