Python:在 class 实例上使用 create_autospec 设置默认值 side_effect

Python: setting default side_effect with create_autospec on class instance

我正在尝试将 side_effect 与 class 上的 unittest.mock.create_autospec 结合使用,将默认实例调用行为设置为 raise NotImplementedError

我面临的问题是:

这是我正在努力实现的代码示例。

# module.py

class MyClass:
    def __init__(self, value):
        self.value = value

    def compute(self):
        return self.value


def foo():
    instance = MyClass(42)
    return instance.compute()
# test_module.py

from unittest.mock import create_autospec
import module
import pytest


@pytest.fixture(autouse=True)
def my_class(monkeypatch):
    # Help me HERE to set side_effect, bellow tests will not work with this settings.
    spec_cls = create_autospec(module.MyClass, side_effect=NotImplementedError)

    monkeypatch.setattr(module, "MyClass", spec_cls)

    return spec_cls("<whatever>")


def test_foo():
    with pytest.raises(NotImplementedError):
        module.foo()


def test_bar(my_class):
    my_class.compute.return_value = 24
    assert module.foo() == 24

不需要使用 autospec :

import unittest.mock as mocking

import pytest

import so71018132_module as module


@pytest.fixture(autouse=True)
def fake_my_class():
    with mocking.patch.object(module.MyClass, "compute") as compute_mock:
        compute_mock.side_effect = NotImplementedError  # default behaviour
        yield compute_mock


def test_foo():
    with pytest.raises(NotImplementedError):
        module.foo()


def test_bar(fake_my_class):
    fake_my_class.side_effect = [24]
    # or alternatively, clear the side_effect then set a return_value :
    # fake_my_class.side_effect = None
    # fake_my_class.return_value = 24
    assert module.foo() == 24

通过 2 项测试。

我完全改变了 fixture 以在 MyClasscompute 方法上使用 unittest.mock.object.patch 所以只是被模拟了,其余的 class 是正常使用的。 另外,我不得不稍微调整 test_bar 代码以正确改变模拟行为。