[英]How can I mock a class and provide a unique object for each set of constructor parameters?
I am adding unit tests to a legacy system.我正在向遗留系统添加单元测试。
There is a Manager
class that creates Worker
objects and performs various operations on them.有一个Manager
类可以创建Worker
对象并对它们执行各种操作。
I want to mock these workers and verify that the manager is creating and using them correctly.我想模拟这些工人并验证经理是否正确创建和使用它们。
To do this I need to be able to create unique mock objects based on the inputs to the constructor.为此,我需要能够根据构造函数的输入创建唯一的模拟对象。
I have not been able to find the right combination of MagicMock
, patch
etc. to make this happen.我一直无法找到MagicMock
、 patch
等的正确组合来实现这一点。
So far I have the following which allows me to return a fixed list of custom mock objects for a test:到目前为止,我有以下内容允许我为测试返回自定义模拟对象的固定列表:
def get_worker_mock(name, param1):
worker = MagicMock(spec=Worker)
worker.name = name
worker.param1 = param1
worker.method1.return_value = "mock_method1_val"
worker.method2.return_value = "mock_method2_val"
return worker
@pytest.fixture(autouse=True)
def worker_fixture():
with patch("mypackage.manager.Worker", spec=Worker) as fixture:
worker1 = get_worker_mock("Worker1", 1)
worker2 = get_worker_mock("Worker2", 2)
fixture.side_effect = [worker1, worker2]
yield fixture
This allows me to run tests assuming that the manager intends to create worker1
followed by worker2
.这允许我运行测试,假设经理打算创建worker1
后跟worker2
。 This is fine, but inflexible.这很好,但不灵活。
What I would like is for the worker_fixture
to be able to construct a unique MagicMock object on the fly based on a call to the Worker
constructor, which may occur several times in a test.我希望worker_fixture
能够基于对Worker
构造函数的调用动态构造一个唯一的 MagicMock 对象,这在测试中可能会发生多次。
The manager class and its tests rely on certain specific properties and methods of the worker, hence I don't believe I can just patch the class like so: manager 类及其测试依赖于 worker 的某些特定属性和方法,因此我不相信我可以像这样修补类:
@patch("mypackage.Worker", autospec=True)
def test_some_manager_test(self, worker_patch):
# Test using the mock...
How can I flexibly create mock objects like this?如何灵活地创建这样的模拟对象?
I would patch the class' contructor, to call the get_worker_mock
, keep the control of the object instances and patches in your side, I dont think @patch
can give you all the behavior you desire.我会修补类的构造get_worker_mock
,调用get_worker_mock
,保持对对象实例和修补程序的控制在你身边,我不认为@patch
可以给你你想要的所有行为。
Create a fixture to do so.创建一个装置来做到这一点。
@pytest.fixture
def patch_worker(monkeypatch):
monkeypatch.setattr(mypackage.manager, 'Worker', get_worker_mock)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.