Pytest 如何从 fixture 获取函数的补丁

Pytest how to have patch for a function from fixture

我正在修补 class 中的一个函数。当我直接在我的测试代码中修补该函数时它可以工作,但是如果我创建一个夹具然后修补(相同的函数),那么我的测试就不起作用(不调用修补函数,但调用实际函数。)

我如何从灯具进行修补?

以下作品

#path directly on test method works
@patch('a.b.MyClass.myFunction')
def test_mypoc(mock_MyClass):
        mock_MyClassFromFixture.returnValue = "dummy"

以下不起作用(尝试从固定装置打补丁,以便可以在多个测试功能中重复使用)

#patch on a fixture
@pytest.fixture(autouse=True, scope="module")
@patch('a.b.MyClass.myFunction')
def mock_MyClassFromFixture(mock_MyClass):
    return mock_MyClass

#test code
def test_mypoc(mock_MyClassFromFixture):
    mock_MyClassFromFixture.returnValue = "dummy"

如果您正在使用 pytest,您可以直接留在 pytest 生态圈内并使用 monkeypatch 来解决这样的问题。

给出以下 class:

class MyClass:
    def fizz(self):
        return "foo"

我们可以将测试修改为运行这样:

import pytest

from src.foo import MyClass


@pytest.fixture(autouse=True)
def mock_MyClassFromFixture(monkeypatch):
    monkeypatch.setattr(MyClass, "fizz", lambda x: "buzz")


def test_MyClass():
    klass = MyClass()
    assert klass.fizz() == "buzz"

有几点需要注意,monkeypatch 是一个 function 作用域固定装置,因此它不能在整个模块中使用,除非您采用提到的方法 here,而且既然您提到如果它是您要修补的函数,则返回的对象应该是可调用的,因此使用 lambda。我们也可以在测试中声明一个函数而不是使用 lambda,但这完全取决于您。