You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何测试函数是否在指定上下文管理器中被调用?

能测试my_function是否在my_context_manager上下文中调用吗?

当然可以,下面是几种实用的测试方式:

1. 用unittest.mock跟踪调用顺序

通过Mock对象记录上下文管理器的__enter__、__exit__方法,以及my_function的调用,然后验证调用顺序——必须是先进入上下文,再调用函数,最后退出上下文。

示例代码:

from unittest.mock import Mock, call

def test_function_runs_in_context():
    # 模拟上下文管理器和目标函数
    mock_ctx = Mock()
    mock_func = Mock()

    # 执行要测试的逻辑
    with mock_ctx():
        mock_func()

    # 验证上下文先进入,函数再调用,最后退出
    assert mock_ctx().__enter__.called
    assert mock_func.called
    assert mock_ctx().__exit__.called

    # 检查调用顺序是否正确
    all_calls = mock_ctx.mock_calls + mock_func.mock_calls
    enter_call_idx = next(i for i, call in enumerate(all_calls) if call[0] == '().__enter__')
    func_call_idx = next(i for i, call in enumerate(all_calls) if call[0] == '')
    exit_call_idx = next(i for i, call in enumerate(all_calls) if call[0] == '().__exit__')

    assert enter_call_idx < func_call_idx < exit_call_idx

2. 给上下文管理器加状态标记

如果能修改上下文管理器的代码,可以给它加个状态属性,比如is_active,然后在函数里或者测试中检查这个状态:

示例代码:

# 自定义带状态的上下文管理器
class MyContextManager:
    def __init__(self):
        self.is_active = False

    def __enter__(self):
        self.is_active = True
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        self.is_active = False

def my_function(ctx):
    # 函数内部直接验证上下文是否激活
    assert ctx.is_active, "my_function必须在上下文管理器中调用"

def test_in_context():
    ctx = MyContextManager()
    with ctx:
        my_function(ctx)  # 这里断言通过
    # 退出上下文后状态应该重置
    assert not ctx.is_active

3. 用副作用捕获上下文状态

如果不想修改原上下文管理器,可以给Mock的__enter__和__exit__加副作用,记录当前是否处于上下文内,然后在函数调用时验证:

from unittest.mock import Mock

def test_with_side_effect():
    in_context = False

    def enter():
        nonlocal in_context
        in_context = True

    def exit(*args):
        nonlocal in_context
        in_context = False

    mock_ctx = Mock()
    mock_ctx().__enter__.side_effect = enter
    mock_ctx().__exit__.side_effect = exit

    def my_function():
        assert in_context, "函数不在上下文里执行"

    with mock_ctx():
        my_function()  # 断言通过

内容的提问来源于stack exchange,提问作者Dušan Maďar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 06:30:37