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
。
我面临的问题是:
- 我不想在 class
__init__
. 上引发异常
- 我不想明确设置所有方法的副作用。
- 我想使用
pytest.fixture
以使我的模拟可通过各种测试重复使用。
这是我正在努力实现的代码示例。
# 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 以在 MyClass
的 compute
方法上使用 unittest.mock.object.patch
所以只是被模拟了,其余的 class 是正常使用的。
另外,我不得不稍微调整 test_bar
代码以正确改变模拟行为。
我正在尝试将 side_effect
与 class 上的 unittest.mock.create_autospec
结合使用,将默认实例调用行为设置为 raise NotImplementedError
。
我面临的问题是:
- 我不想在 class
__init__
. 上引发异常
- 我不想明确设置所有方法的副作用。
- 我想使用
pytest.fixture
以使我的模拟可通过各种测试重复使用。
这是我正在努力实现的代码示例。
# 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 以在 MyClass
的 compute
方法上使用 unittest.mock.object.patch
所以只是被模拟了,其余的 class 是正常使用的。
另外,我不得不稍微调整 test_bar
代码以正确改变模拟行为。