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

如何用pytest-mock分别模拟两个pathlib.Path实例的exists方法,测试主文件存在但关联文件缺失的场景

如何用pytest-mock分别模拟两个pathlib.Path实例的exists方法,测试主文件存在但关联文件缺失的场景

你遇到的问题本质是:pathlib.Path的exists是类绑定的实例方法,单个Path实例的exists属性是只读的,没法直接覆盖赋值,所以直接mock实例的exists会报错。下面给你提供两种靠谱的解决思路,都是通过mock类的exists方法,同时区分不同实例的返回值:

方法一:通过side_effect根据实例判断返回值

这是最直接且健壮的方式,我们给pathlib.Path.exists的mock设置一个side_effect函数,这个函数会接收当前调用的Path实例作为第一个参数(也就是self),然后根据实例判断返回True还是False:

def test_main_file_exists_second_missing(mocker):
    # 定义测试用的目标文件
    target_file = pathlib.Path("test.txt")
    # 提前计算出预期的第二个文件路径
    expected_second_file = target_file.parent / f"{target_file.stem}_second{target_file.suffix}"

    # 定义判断逻辑:只有当实例是目标文件时返回True,其他都返回False
    def mock_exists(self):
        return self == target_file

    # 替换Path类的exists方法,使用我们的判断逻辑
    mocker.patch("pathlib.Path.exists", side_effect=mock_exists)

    # 执行测试,验证抛出SecondFileError
    with pytest.raises(SecondFileError):
        check_files(target_file)

这个测试的执行流程是:

  1. 调用check_files(target_file)时,先检查target_file.exists(),此时self是target_file,返回True
  2. 生成expected_second_file后,调用它的exists(),此时self是第二个文件实例,返回False
  3. 触发SecondFileError,测试通过

如果担心Path实例的__eq__判断有问题(比如相对/绝对路径差异),也可以用路径字符串来判断:

def mock_exists(self):
    return str(self) == str(target_file)

方法二:用MagicMock按调用顺序控制返回值(适合简单场景)

如果能确定exists方法的调用顺序,也可以用列表直接指定返回值顺序,这种方式更简洁但依赖调用顺序:

def test_main_file_exists_second_missing(mocker):
    target_file = pathlib.Path("test.txt")
    
    # 先mock Path.exists方法
    mock_exists = mocker.patch("pathlib.Path.exists")
    # 设置返回顺序:第一次调用返回True(主文件),第二次返回False(关联文件)
    mock_exists.side_effect = [True, False]

    with pytest.raises(SecondFileError):
        check_files(target_file)

注意:这种方式仅适用于你能确保exists的调用顺序不会改变的场景,如果后续代码修改了调用逻辑,测试会直接失败,所以更推荐第一种方法。

为什么你之前的尝试失败?

  • 直接给Path实例赋值exists:Path的exists是从类继承的方法,实例的这个属性是只读的,没法直接覆盖
  • patch实例的exists属性:同样因为实例的exists是只读的,patch操作会触发AttributeError
  • mock__getattr__:Path类本身没有定义__getattr__方法,所以mock这个属性也会报错

备注:内容来源于stack exchange,提问作者3dSpatialUser

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.14 14:25:27