web-dev-qa-db-fra.com

Comment patcher une constante dans python

J'ai deux modules différents dans mon projet. L'un est un fichier de configuration qui contient

LOGGING_ACTIVATED = False

Cette constante est utilisée dans le deuxième module (appelons-la main) comme suit:

if LOGGING_ACTIVATED:
    amqp_connector = Connector()

Dans ma classe de test pour le module principal, je voudrais patcher cette constante avec la valeur

True

Malheureusement, ce qui suit ne fonctionne pas

@patch("config.LOGGING_ACTIVATED", True)

cela ne fonctionne pas non plus:

@patch.object("config.LOGGING_ACTIVATED", True)

Quelqu'un sait-il comment patcher une constante de différents modules?

23
d.a.d.a

Si la if LOGGING_ACTIVATED: le test se produit au niveau du module , vous devez vous assurer que ce module n'est pas encore importé en premier. Le code au niveau du module ne s'exécute qu'une seule fois (la première fois que le module est importé), vous ne pouvez pas tester le code qui ne s'exécutera plus.

Si le test est dans une fonction, notez que le nom global utilisé est LOGGING_ACTIVATED, pas config.LOGGING_ACTIVATED. En tant que tel, vous devez patcher main.LOGGING_ACTIVATED ici:

@patch("main.LOGGING_ACTIVATED", True)

car c'est la référence que vous vouliez remplacer.

Voir également la section Où corriger de la documentation mock.

Vous devriez envisager de refactoriser le code au niveau du module en quelque chose de plus testable. Bien que vous puissiez forcer le rechargement du code du module en supprimant l'objet module du sys.modules mappage, il est plus simple de déplacer le code que vous souhaitez tester dans une fonction.

Donc, si votre code ressemble maintenant à ceci:

if LOGGING_ACTIVATED:
    amqp_connector = Connector()

envisagez plutôt d'utiliser une fonction:

def main():
    global amqp_connector
    if LOGGING_ACTIVATED:
        amqp_connector = Connector()

main()

ou produire un objet avec des attributs même.

39
Martijn Pieters