web-dev-qa-db-ja.com

pythonで定数をパッチする方法

私のプロジェクトには2つの異なるモジュールがあります。 1つは、以下を含む構成ファイルです。

LOGGING_ACTIVATED = False

この定数は、次のように2番目のモジュールで使用されます(これをメインと呼びます)。

if LOGGING_ACTIVATED:
    amqp_connector = Connector()

メインモジュールのテストクラスで、この定数に値をパッチしたい

True

残念ながら、以下は機能しません

@patch("config.LOGGING_ACTIVATED", True)

これも機能しません:

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

誰かが異なるモジュールから定数をパッチする方法を知っていますか?

23
d.a.d.a

if LOGGING_ACTIVATED:テストがモジュールレベルで発生する場合は、最初にそのモジュールがまだインポートされていないことを確認する必要があります。モジュールレベルのコードは1回だけ実行されます(モジュールが初めてどこかにインポートされたとき)、再度実行されないコードをテストすることはできません。

テストが関数内にある場合、使用されるグローバル名はLOGGING_ACTIVATEDnotconfig.LOGGING_ACTIVATEDであることに注意してください。そのため、ここでmain.LOGGING_ACTIVATEDにパッチを適用する必要があります。

@patch("main.LOGGING_ACTIVATED", True)

置換したい実際の参照なので。

mockドキュメントの Where to patchsection も参照してください。

モジュールレベルのコードをよりテストしやすいものにリファクタリングすることを検討する必要があります。 sys.modulesマッピングからモジュールオブジェクトを削除することでモジュールコードの再読み込みを強制できますが、テストしたいコードを関数に移動する方が簡単です。

したがって、コードが次のようになっているとします。

if LOGGING_ACTIVATED:
    amqp_connector = Connector()

代わりに関数の使用を検討してください:

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

main()

または、属性を持つオブジェクトを生成します。

39
Martijn Pieters