Explain how to properly mock user-defined `__call__`
オープン
まだ誰も着手していません。
docs
- 主要言語
- Python
- スター
- 77.2k
- フォーク
- 35.9k
- PR マージ指標
- PR 指標を取得中
説明
Bug report
Bug description:
Reproduce
from unittest.mock import MagicMock
class A:
def __init__(self, a):
...
def __call__(self, b, c):
...
mocker = MagicMock(spec=A)
mocker(21, 42)
mocker.assert_called_once_with(21, 42)
Current Behavior
TypeError Traceback (most recent call last)
TypeError: too many positional arguments
The above exception was the direct cause of the following exception:
AssertionError Traceback (most recent call last)
Cell In[6], line 10
8 mocker = MagicMock(spec=A)
9 mocker(21, 42)
---> 10 mocker.assert_called_once_with(21, 42)
File ~/.pyenv/versions/3.12.2/lib/python3.12/unittest/mock.py:956, in NonCallableMock.assert_called_once_with(self, *args, **kwargs)
951 msg = ("Expected '%s' to be called once. Called %s times.%s"
952 % (self._mock_name or 'mock',
953 self.call_count,
954 self._calls_repr()))
955 raise AssertionError(msg)
--> 956 return self.assert_called_with(*args, **kwargs)
File ~/.pyenv/versions/3.12.2/lib/python3.12/unittest/mock.py:944, in NonCallableMock.assert_called_with(self, *args, **kwargs)
942 if actual != expected:
943 cause = expected if isinstance(expected, Exception) else None
--> 944 raise AssertionError(_error_message()) from cause
AssertionError: expected call not found.
Expected: mock(21, 42)
Actual: mock(21, 42)
Expected behaviour
It succeeds
Investigation
When passing a class that implements the __call__ method as spec to a mock instance it takes the it takes the signature of the __init__ which if it is the intended behavior is quite confusing.
CPython versions tested on:
3.12, 3.13
Operating systems tested on:
macOS, Linux
コントリビューションガイド
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
調査の方向性
Python 3.12 または 3.13 で、提供されている MagicMock の再現コードから始め、続いて unittest/mock.py の NonCallableMock.assert_called_with 周辺と、spec=A に関係するシグネチャ処理を調べます。call を定義しているクラスの動作を、現在の traceback と比較します。示されている assertion が成功するように、文書化された動作または実装された動作になっていれば完了です。
索引モデルが issue の本文から書いたものです。
評価
- 技術スタック
- python
- 領域
- testing-qa
- issue の種類
- バグ
- 難易度
- 4/5
- 見積もり時間
- 3〜5日
- 活発さ
- 停滞
- 明瞭さ
- おおむね明確
- 初心者へのやさしさ
- 42/100