Explain how to properly mock user-defined `__call__`
Personne n'a encore pris cette issue.
- Langage dominant
- Python
- Étoiles
- 77.2k
- Forks
- 35.9k
- Métriques de merge des PR
- Métriques de PR en attente
Description
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
Guide de contribution
Ouvrir le guide de contribution
Par où commencer
- Lisez l'issue en entier, puis le guide de contribution du projet.
- Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
- Forkez le dépôt et travaillez sur une branche.
- Ouvrez une pull request qui référence le numéro de l'issue.
Piste de recherche
Commencez par le reproducteur MagicMock fourni avec Python 3.12 ou 3.13, puis examinez unittest/mock.py autour de NonCallableMock.assert_called_with ainsi que la gestion de la signature impliquée par spec=A. Comparez le comportement d’une classe définissant call avec le traceback actuel. Le travail est terminé lorsque le comportement documenté ou implémenté permet à l’assertion montrée de réussir.
Rédigé par le modèle d'indexation à partir du texte de l'issue.
Évaluation
- Stack technique
- python
- Domaine
- testing-qa
- Type d'issue
- Bug
- Difficulté
- 4/5
- Temps estimé
- 3-5 jours
- Activité
- À l'abandon
- Clarté
- Plutôt claire
- Accessibilité débutants
- 42/100