代码之家  ›  专栏  ›  技术社区  ›  Micah Pearce

Pytest:如何调用fixture的补丁

  •  0
  • Micah Pearce  · 技术社区  · 6 年前

    pytest 5.0.1版 python 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中取出补丁来使用它。我尝试创建一个新的补丁,但这不起作用(例如assert 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    
    

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

    0 回复  |  直到 6 年前
        1
  •  0
  •   MrBean Bremen    6 年前

    我想你想修补一下 Client.execute 在里面 A ,并且夹具应返回类型为的对象 A 有了补丁。首先要确保修补程序仍处于活动状态:

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

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

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

    或者,您可以在fixture中返回mock本身:

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

    这样你就可以明确地在你的测试中创建这个对象,在我看来,测试更加清晰。

    (我想不通,所以可能有错误…)

    推荐文章