Python Monkey Patch无法撤销,导致单元测试用例相互干扰求助
解决pytest monkeypatch无法撤销修改的问题
问题根源
- 手动调用
monkeypatch.undo()的误区:pytest的monkeypatchfixture默认会在测试用例执行完毕后自动撤销所有通过它做的修改,手动调用undo()会提前撤销单个修改,反而可能打乱内部的撤销队列,导致后续自动撤销逻辑异常。 - 未用monkeypatch管理
dependency_overrides:直接修改app.dependency_overrides[check_token]的操作不在monkeypatch的管理范围内,所以即使调用undo()也不会清理这部分内容,残留的修改会影响其他测试用例。
修正方案
方案1:移除手动undo(),用monkeypatch统一管理所有修改
将dependency_overrides的修改也交给monkeypatch处理,这样所有修改都会在测试结束后自动被撤销:
@pytest.mark.asyncio async def test_my_method(monkeypatch): # 用monkeypatch.setitem管理dependency_overrides的赋值 monkeypatch.setitem(app.dependency_overrides, check_token, override_token_expired) async def mock_cosmos_query(*args, **kwargs): return fake_spaces monkeypatch.setattr('app.routers.space.cosmos_query', mock_cosmos_query) response = client.get("/api/spaces/TestSpace", headers={"authorization": "fake user"}, params={"expand": "false"}) jsonObj = response.json() assert response.status_code == 200 assert jsonObj['name'] == 'TestSpace' # 移除monkeypatch.undo(),让pytest自动处理撤销
方案2:手动清理dependency_overrides(备选)
如果不想用monkeypatch管理dependency_overrides,可以在测试结束后手动恢复该字典的原始状态:
@pytest.mark.asyncio async def test_my_method(monkeypatch): original_override = app.dependency_overrides.get(check_token) app.dependency_overrides[check_token] = override_token_expired async def mock_cosmos_query(*args, **kwargs): return fake_spaces monkeypatch.setattr('app.routers.space.cosmos_query', mock_cosmos_query) response = client.get("/api/spaces/TestSpace", headers={"authorization": "fake user"}, params={"expand": "false"}) jsonObj = response.json() assert response.status_code == 200 assert jsonObj['name'] == 'TestSpace' # 手动恢复dependency_overrides if original_override is None: del app.dependency_overrides[check_token] else: app.dependency_overrides[check_token] = original_override # 移除monkeypatch.undo(),让pytest自动处理setattr的撤销
关键注意事项
- 除非明确需要撤销单个修改且不依赖自动清理,否则不要在测试用例中手动调用
monkeypatch.undo()。 - 所有需要在测试后恢复的全局修改,都应该通过
monkeypatch的方法(setattr/setitem/delattr等)来操作,确保它们被纳入自动撤销的管理中。
内容的提问来源于stack exchange,提问作者DevHelp
相关产品推荐
相关产品推荐

