Lorsque le code source a été initialement lu, la fonction submethod_b
d'origine était déjà stockée dans la variable _method_registry
, donc au moment où vous l'avez corrigée à l'exécution, bien que la fonction ait été remplacée, elle n'a pas modifié la valeur déjà stockée dans cette variable. Pour le prouver, ajoutons des impressions.
main.py
def submethod_a():
pass
def submethod_b():
pass
_method_registry = {
"a": submethod_a,
"b": submethod_b,
}
def main_method(key):
print(_method_registry["b"], "- Fonction stockée")
print(submethod_b, "- Fonction corrigée")
test_main.py
from unittest.mock import patch
from main import main_method
def test_no_patch():
main_method("b")
@patch("main.submethod_b")
def test_with_patch(mocked_submethod_b):
main_method("b")
Sortie
$ pytest -q -rP
================================================================================================= RÉUSSITES ==================================================================================================
______________________________________________________________________________________________ test_no_patch ______________________________________________________________________________________________
------------------------------------------------------------------------------------------ Sortie stdout -------------------------------------------------------------------------------------------
- Fonction stockée
- Fonction corrigée
_____________________________________________________________________________________________ test_with_patch _____________________________________________________________________________________________
------------------------------------------------------------------------------------------ Sortie stdout -------------------------------------------------------------------------------------------
- Fonction stockée
- Fonction corrigée
2 passed in 0.04s
Comme vous pouvez le voir, sans le patch, la valeur est simplement la même fonction d'origine. Mais avec le patch, remarquez que seule la fonction effective a été remplacée, pas celle déjà stockée.
Solution Alternative
- Placez les fonctions submethod dans leur propre fichier.
- Importez les subméthodes dans votre fichier principal et utilisez-les comme initialement fait.
- Corrigez le fichier subméthode.
- Rechargez le fichier principal pour que les subméthodes corrigées soient utilisées lors de la recréation du
_method_registry
.
main.py
from submethod import submethod_a, submethod_b # Ou : import submethod
_method_registry = {
"a": submethod_a, # En fonction du style d'importation choisi, cela peut être : submethod.submethod_a
"b": submethod_b, # En fonction du style d'importation choisi, cela peut être : submethod.submethod_b
}
def main_method(key):
print(_method_registry["b"], "- Fonction stockée")
print(submethod_b, "- Fonction corrigée")
methode_a_utiliser = _method_registry[key]
methode_a_utiliser()
submethod.py
def submethod_a():
pass
def submethod_b():
pass
test_main.py
from importlib import reload
import sys
from unittest.mock import patch
from main import main_method
@patch("submethod.submethod_b")
def test_with_patch(mocked_submethod_b):
# Maintenant que le patch est en effet et a remplacé le submethod.submethod_b, recharger le fichier principal pour recréer _method_registry avec la fonction corrigée
reload(sys.modules['main'])
main_method("b")
assert mocked_submethod_b.called
Sortie
$ pytest -q -rP
================================================================================================= RÉUSSITES ==================================================================================================
_____________________________________________________________________________________________ test_with_patch _____________________________________________________________________________________________
------------------------------------------------------------------------------------------ Sortie stdout -------------------------------------------------------------------------------------------
- Fonction stockée
- Fonction corrigée
1 passed in 0.04s
Maintenant, la fonction stockée et la fonction corrigée elles-mêmes pointent toutes les deux vers la version simulée. Ainsi, l'assertion .called
est maintenant réussie.