首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在python3中模拟配置变量?

如何在python3中模拟配置变量?
EN

Stack Overflow用户
提问于 2021-09-28 10:14:06
回答 1查看 813关注 0票数 2

这是一个AWS lambda函数

代码语言:javascript
复制
#service.py
from configs import SENDER, DESTINATIONS
from constants import LOG_FORMAT
import logging

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

在配置文件中,它从AWS param存储中检索数据

代码语言:javascript
复制
# 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)
...

所以当我试着测试它

代码语言:javascript
复制
# 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文件。因此,要调用AWS,就需要使用sec证书。作为一种解决方案,我尝试过嘲笑发送者和目的地。但是它抛出了错误(期望安全令牌)

我希望单元独立于安全令牌。提出解决办法

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-09-28 13:08:19

这是因为当您导入configs.py (例如通过from configs import SENDER, DESTINATION )时,它会自动运行那些调用load_parameters的语句,这些语句反过来调用AWS,即使还没有活动的模拟/补丁程序。

解决方案1

尝试重构configs.py,使变量的设置只发生在显式调用(而不是导入时)。最简单的实现是这样的:

configs.py

代码语言:javascript
复制
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),
    }

这需要一些重构,因为对get_params的调用必须在AWS函数调用开始时插入。这样,使用AWS的load_parameters调用就不会自动执行,我们可以在调用它之前准备模拟/补丁。

解决方案2

当还没有活动的模拟/修补程序时,不要导入任何反过来会导入configs.py的文件。首先修补load_parameters,这样它就不会连接到实际的AWS。您可以手动修补它,也可以使用来自莫托的装饰器莫托。只有这样,我们才能安全地导入文件。

代码语言:javascript
复制
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(...)
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69359854

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档