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

Python Mockito库spy2作用于builtins.open时异常问题咨询

Why does Mockito's spy2 behave differently for builtins.open vs os.path.exists?

Great question! The discrepancy you're seeing comes down to how Mockito-python handles built-in functions versus regular module functions. Let's break this down step by step:

1. The Core Behavior Difference

When you use spy2 on a regular module function like os.path.exists:

  • Mockito creates a proxy wrapper around the real function.
  • For any call that doesn't match your stubbed arguments (e.g., folder_that_doesnt_exist), the proxy automatically forwards the call to the original os.path.exists implementation.
  • Only the explicitly stubbed argument (.flake8) uses your custom return value.

But with builtins.open:

  • open is a built-in function implemented in C (not pure Python), and its function object has a different internal structure than regular module functions.
  • Mockito's spy2 can't properly create a proxy that falls back to the real implementation for unmatched calls. Instead, it defaults to strict stubbing mode—meaning every call to open must match an explicitly defined stub, otherwise it throws an InvocationError.

2. How to Fix It

To get the behavior you expect (stub only specific arguments, let others use the real open), you need to explicitly tell Mockito to fall back to the real method for unmatched calls. Add a catch-all stub that calls the real function before your specific stub:

import builtins
import mockito

mockito.spy2(builtins.open)
# First, set a catch-all stub to call the real method for any unmatched arguments
mockito.when(builtins).open(...).thenCallRealMethod()
# Then add your specific stub
mockito.when(builtins).open("not_existing_file.csv").thenReturn("test")

print(builtins.open("not_existing_file.csv"))  # Outputs "test"
print(builtins.open("__init__.py"))            # Opens the real file as expected

mockito.unstub()

The ... (ellipsis) acts as a wildcard for any arguments, ensuring all calls that don't match your specific stub are forwarded to the real open function.

3. Why This Happens Under the Hood

Mockito-python relies on inspecting Python function objects to create its spy proxies. Built-in functions (from the builtins module) don't expose the same internal hooks as pure Python functions in regular modules. This makes it impossible for Mockito to automatically forward unmatched calls to the real implementation, so it switches to strict mode as a fallback.

Regular module functions like os.path.exists are pure Python (or at least expose a compatible function interface), so Mockito can wrap them properly to preserve the default real behavior.

内容的提问来源于stack exchange,提问作者Naindlac

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.27 21:22:46