簡體   English   中英

如何在 python3 中模擬配置變量?

[英]How to mock config variables in python3?

這是一個 AWS lambda function

#service.py
from configs import SENDER, DESTINATIONS
from constants import LOG_FORMAT
import logging

def send_mail(body, SENDER, DESTINATIONS):
    ...
    ...

在配置文件中,它從 AWS 參數存儲中檢索數據

# configs.py
from handlers.ssm_handler import load_parameters
from common import constants
import os
environment = os.environ.get(constants.ENVIRONMENT)

JSON_BUCKET = load_parameters(constants.OT_ARCHIVAL_PREFIX+environment+constants.MIGRATION_BUCKET)
SENDER = load_parameters(constants.OT_ARCHIVAL_PREFIX+environment+constants.MAIL_SENDER)
DESTINATIONS = load_parameters(constants.OT_ARCHIVAL_PREFIX+environment+constants.MAIL_DESTINATIONS)
...

所以當我嘗試測試它時

# test_service.py
from unittest import TestCase, main, mock
from service import send_mail

class TestMailService(TestCase):
     def test_service(self):
       with mock.patch('service.SENDER', 'abc@sys.com') as mocked_sender:
         with mock.patch('service.DESTINATIONS', 'def@sys.com') as mocked_sender:
           with mock.patch('service.logging.Logger.info') as mocked_logging:
              send_mail(...)
              mocked_logging.assert_called_with('mail sent Successfully')

當我導出 AWS 安全憑證時,此測試用例通過。 但它不會,如果我不通過憑據。 我猜這是因為在 service.py 文件中它打開了整個 config.py 文件。 因此它需要 sec 憑據才能調用 AWS。 作為解決方案,我嘗試了 mocking SENDER 和 DESTINATIONS。 但它拋出我錯誤(期待安全令牌)

我希望單元測試獨立於安全令牌。 建議解決方案

發生這種情況是因為當您通過from configs import SENDER, DESTINATION導入configs.py時,它會自動運行那些調用load_parameters的語句,即使還沒有活動的模擬/補丁,這些語句又會調用 AWS SSM。

解決方案 1

嘗試重構configs.py ,使變量的設置只發生在顯式調用時(而不是導入時)。 最簡單的實現是這樣的:

配置.py

import os

from common import constants
from handlers.ssm_handler import load_parameters


def get_params():
    environment = os.environ.get(constants.ENVIRONMENT)
    return {
        "SENDER": load_parameters(constants.OT_ARCHIVAL_PREFIX+environment+constants.MAIL_SENDER),
        "DESTINATIONS": load_parameters(constants.OT_ARCHIVAL_PREFIX+environment+constants.MAIL_DESTINATIONS),
    }

這需要進行一些重構,因為必須在 AWS Lambda function 調用的開頭插入對get_params的調用。 這樣,調用load_parameters又使用 AWS SSM 的調用將不會自動執行,我們可以在調用之前准備我們的模擬/補丁。

方案二

當還沒有活動的模擬/補丁時,不要導入任何會依次導入configs.py的文件。 首先修補load_parameters ,使其不連接到實際的 AWS SSM。 您可以手動修補它,也可以使用來自moto的裝飾器@mock_ssm 只有這樣我們才能安全地導入文件。

from unittest import TestCase, main, mock

from moto import mock_ssm

# from service import send_mail  # REMOVE THIS IMPORT!


@mock_ssm  # Option 1. Requires <pip install moto>. You have to setup SSM first as usual.
def test_service(mocker):  # Requires <pip install pytest-mock>
    mocker.patch('handlers.ssm_handler.load_parameters')  # Option 2
    # with mock.patch('handlers.ssm_handler.load_parameters') as mock_ssm:  # Option 3. This is equivalent to Option 2.

    mocker.patch('service.SENDER', 'abc@sys.com')
    mocker.patch('service.DESTINATIONS', 'def@sys.com')

    from service import send_mail  # Import it here after the patches have taken effect
    send_mail(...)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM