试图模拟修补一个函数,但得到 PIL\\Image.py'> 没有属性 'save'

Trying to mock patch a function, but getting PIL\\Image.py'> does not have the attribute 'save'

我正在使用 pytest-mock,但是抛出的异常来自 mock.patch 代码,我已经验证如果我使用 @mock.patch 装饰器语法也会发生同样的错误。

MRE(确保安装了 pytest 和 pytest-mock,无需导入任何东西):

def test_image(mocker):
    mocker.patch("PIL.Image.save")

现在 运行 对该模块进行 pytest。

错误:

E           AttributeError: <module 'PIL.Image' from 'c:\users\...\site-packages\PIL\Image.py'> does not have the attribute 'save'

我看得很清楚 Image.py 确实包含一个 函数 叫 save,但是函数不被认为是属性吗?我从来没有听说过这个词用于模块的内容。

savePIL.Image.Image class 而不是 PIL.Image 模块的实例方法。

您应该将补丁实施为:

def test_image(mocker):
    mocker.patch("PIL.Image.Image.save")

如果您需要断言 save 方法在 Image 实例上被调用,您需要一个绑定到 mock 的 name . 您可以通过模拟 Image class 并将 Mock 实例绑定到它的 save 方法来实现它。例如,

def test_image(mocker):
    # prepare
    klass = mocker.patch("PIL.Image.Image")
    instance = klass.return_value
    instance.save = mocker.Mock() 
    
    # act
    # Do operation that invokes save method on `Image` instance

    # test
    instance.save.assert_called()