需要有关如何在Moto中创建相同环境的帮助,以便我的Python测试工作

发布于 2025-01-24 09:08:17 字数 5080 浏览 5 评论 0原文

我需要有关如何在Moto中创建相同环境的帮助,以便我的Python测试工作

该代码在Python中撰写,并使用Unittest,Boto3和Moto实施了测试。

2个文件包含在同一目录中,称为

正在测试的主文件(lambda_function.py) 测试文件(test_api_login.py)

请参阅错误输出,

/usr/bin/python3 "/Applications/PyCharm CE.app/Contents/plugins/python-ce/helpers/pycharm/_jb_pytest_runner.py" --target test_api_login.py::test_login_to_api
Testing started at 12:24 PM ...
Launching pytest with arguments test_api_login.py::test_login_to_api --no-header --no-summary -q in /Users/myk/Documents/DUMP/apiLogin

============================= test session starts ==============================
collecting ... collected 1 item

test_api_login.py::test_login_to_api::test_my_test FAILED    [100%]
test_api_login.py:16 (test_login_to_api.test_my_test)
moto/core/models.py:118: in wrapper
    result = func(*args, **kwargs)
/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.8/lib/python3.8/unittest/mock.py:1322: in patched
    with self.decoration_helper(patched,
/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.8/lib/python3.8/contextlib.py:113: in __enter__
    return next(self.gen)
/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.8/lib/python3.8/unittest/mock.py:1304: in decoration_helper
    arg = exit_stack.enter_context(patching)
/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.8/lib/python3.8/contextlib.py:425: in enter_context
    result = _cm_type.__enter__(cm)
/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.8/lib/python3.8/unittest/mock.py:1377: in __enter__
    self.target = self.getter()
/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.8/lib/python3.8/unittest/mock.py:1552: in <lambda>
    getter = lambda: _importer(target)
/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.8/lib/python3.8/unittest/mock.py:1224: in _importer
    thing = __import__(import_path)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

    import requests
    import json
    
    import boto3
    
    ssm = boto3.client('ssm', region_name="us-east-1")
    base_url_obj = ssm.get_parameters(Names=["/prof-svc-int/dev/api-base-url"])
>   BASE_URL = base_url_obj['Parameters'][0]['Value']
E   IndexError: list index out of range

lambda_function.py:8: IndexError




============================== 1 failed in 3.28s ===============================

Process finished with exit code 1

请参阅要测试的主文件的代码(lambda_function.py),

import requests
import json

import boto3

ssm = boto3.client('ssm', region_name="us-east-1")
base_url_obj = ssm.get_parameters(Names=["/prof-svc-int/dev/api-base-url"])
BASE_URL = base_url_obj['Parameters'][0]['Value']

username_obj = ssm.get_parameters(Names=["/prof-svc-int/dev/api-username"])
USERNAME = username_obj['Parameters'][0]['Value']

password_obj = ssm.get_parameters(Names=["/prof-svc-int/dev/api-password"])
PASSWORD = password_obj['Parameters'][0]['Value']


def lambda_handler(event, context):
    username = USERNAME
    password = PASSWORD

    message = ''
    code = 400

    headers = {"Accept": "application/json", "Content-Type": "application/json"}

    try:
        url = f"{BASE_URL}v0/login"

        data = {"username": username, "password": password}

        r = requests.post(url, headers=headers, data=json.dumps(data))
        message = r.json()

    except Exception as e:
        message += f'An error occurred  {str(e)}'

    if "token" in message:
        token = message['token']
        print("token >> " + token)
        put_response = ssm.put_parameter(
            Name='/prof-svc-int/dev/api-token',
            Value=token,
            Type='String',
            Overwrite=True
        )
        print("put_response >> ", put_response)
        code = 200
    output = OutputObj(code,
                       message)

    json_str = json.dumps(output.__dict__)

    result = json.loads(json_str)

    return result


class OutputObj:
    def __init__(self, statusCode, body):
        self.statusCode = statusCode
        self.body = body

请参阅test文件的代码(test_api_login.py)

import unittest
from unittest.mock import patch
from moto import mock_ssm


@mock_ssm
@patch("lambda_function.lambda_handler.base_url_obj")
@patch("lambda_function.lambda_handler.BASE_URL")
@patch("lambda_function.lambda_handler.username_obj")
@patch("lambda_function.lambda_handler.USERNAME")
@patch("lambda_function.lambda_handler.password_obj")
@patch("lambda_function.lambda_handler.PASSWORD")
class test_login_to_api(unittest.TestCase):
    @mock_ssm
    def test_my_test(self):

        with patch('lambda_function.lambda_handler') as mock_post:
            mock_post.return_value.statusCode = 200

            out = mock_post
            code = out.code
            self.assertEqual(code, 200)

    if __name__ == "__main__":
        unittest.main()

I need help on how to re create the same environment in moto so my python tests work

The code is writen in python and tests were implemented using unittest, boto3, and moto.

2 files are contained in the same directory called

Main file being tested (lambda_function.py)
Test File (test_api_login.py)

See the errors output

/usr/bin/python3 "/Applications/PyCharm CE.app/Contents/plugins/python-ce/helpers/pycharm/_jb_pytest_runner.py" --target test_api_login.py::test_login_to_api
Testing started at 12:24 PM ...
Launching pytest with arguments test_api_login.py::test_login_to_api --no-header --no-summary -q in /Users/myk/Documents/DUMP/apiLogin

============================= test session starts ==============================
collecting ... collected 1 item

test_api_login.py::test_login_to_api::test_my_test FAILED    [100%]
test_api_login.py:16 (test_login_to_api.test_my_test)
moto/core/models.py:118: in wrapper
    result = func(*args, **kwargs)
/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.8/lib/python3.8/unittest/mock.py:1322: in patched
    with self.decoration_helper(patched,
/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.8/lib/python3.8/contextlib.py:113: in __enter__
    return next(self.gen)
/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.8/lib/python3.8/unittest/mock.py:1304: in decoration_helper
    arg = exit_stack.enter_context(patching)
/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.8/lib/python3.8/contextlib.py:425: in enter_context
    result = _cm_type.__enter__(cm)
/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.8/lib/python3.8/unittest/mock.py:1377: in __enter__
    self.target = self.getter()
/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.8/lib/python3.8/unittest/mock.py:1552: in <lambda>
    getter = lambda: _importer(target)
/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.8/lib/python3.8/unittest/mock.py:1224: in _importer
    thing = __import__(import_path)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

    import requests
    import json
    
    import boto3
    
    ssm = boto3.client('ssm', region_name="us-east-1")
    base_url_obj = ssm.get_parameters(Names=["/prof-svc-int/dev/api-base-url"])
>   BASE_URL = base_url_obj['Parameters'][0]['Value']
E   IndexError: list index out of range

lambda_function.py:8: IndexError




============================== 1 failed in 3.28s ===============================

Process finished with exit code 1

See the code for the main file being tested (lambda_function.py)

import requests
import json

import boto3

ssm = boto3.client('ssm', region_name="us-east-1")
base_url_obj = ssm.get_parameters(Names=["/prof-svc-int/dev/api-base-url"])
BASE_URL = base_url_obj['Parameters'][0]['Value']

username_obj = ssm.get_parameters(Names=["/prof-svc-int/dev/api-username"])
USERNAME = username_obj['Parameters'][0]['Value']

password_obj = ssm.get_parameters(Names=["/prof-svc-int/dev/api-password"])
PASSWORD = password_obj['Parameters'][0]['Value']


def lambda_handler(event, context):
    username = USERNAME
    password = PASSWORD

    message = ''
    code = 400

    headers = {"Accept": "application/json", "Content-Type": "application/json"}

    try:
        url = f"{BASE_URL}v0/login"

        data = {"username": username, "password": password}

        r = requests.post(url, headers=headers, data=json.dumps(data))
        message = r.json()

    except Exception as e:
        message += f'An error occurred  {str(e)}'

    if "token" in message:
        token = message['token']
        print("token >> " + token)
        put_response = ssm.put_parameter(
            Name='/prof-svc-int/dev/api-token',
            Value=token,
            Type='String',
            Overwrite=True
        )
        print("put_response >> ", put_response)
        code = 200
    output = OutputObj(code,
                       message)

    json_str = json.dumps(output.__dict__)

    result = json.loads(json_str)

    return result


class OutputObj:
    def __init__(self, statusCode, body):
        self.statusCode = statusCode
        self.body = body

See the code for test File (test_api_login.py)

import unittest
from unittest.mock import patch
from moto import mock_ssm


@mock_ssm
@patch("lambda_function.lambda_handler.base_url_obj")
@patch("lambda_function.lambda_handler.BASE_URL")
@patch("lambda_function.lambda_handler.username_obj")
@patch("lambda_function.lambda_handler.USERNAME")
@patch("lambda_function.lambda_handler.password_obj")
@patch("lambda_function.lambda_handler.PASSWORD")
class test_login_to_api(unittest.TestCase):
    @mock_ssm
    def test_my_test(self):

        with patch('lambda_function.lambda_handler') as mock_post:
            mock_post.return_value.statusCode = 200

            out = mock_post
            code = out.code
            self.assertEqual(code, 200)

    if __name__ == "__main__":
        unittest.main()

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

遗心遗梦遗幸福 2025-01-31 09:08:17

您可以使用boto3重新创建相同的环境。考虑到您正在读取三个SSM参数,您可以创建这些相同的参数作为设置方法的一部分:

@mock_ssm
@patch("lambda_function.lambda_handler.base_url_obj")
@patch("lambda_function.lambda_handler.BASE_URL")
@patch("lambda_function.lambda_handler.username_obj")
@patch("lambda_function.lambda_handler.USERNAME")
@patch("lambda_function.lambda_handler.password_obj")
@patch("lambda_function.lambda_handler.PASSWORD")
class test_login_to_api(unittest.TestCase):

    def setUp(self) -> None:
        ssm = boto3.client("ssm", "us-east-1")
        mock_values = [("/prof-svc-int/dev/api-base-url", "MY_BASE_URL"),
                       ("/prof-svc-int/dev/api-username", "MY_USERNAME"),
                       ("/prof-svc-int/dev/api-password", "MY_PASSWORD")]
        for key, val in mock_values:
            ssm.put_parameter(
                Name=key,
                Description=f"Mock value for {key}",
                Value=val,
                Type="String"
            )

    def test_my_test(self):
        # as usual
        # all parameters are now present in 'us-east-1'
        pass

请注意,我在测试方法本身上删除了mock_ssm decorator,您只需要在课堂本身上使用它。

You can use boto3 to recreate the same environment. Considering you are reading three SSM parameters, you can create these same parameters as part of the setUp-method:

@mock_ssm
@patch("lambda_function.lambda_handler.base_url_obj")
@patch("lambda_function.lambda_handler.BASE_URL")
@patch("lambda_function.lambda_handler.username_obj")
@patch("lambda_function.lambda_handler.USERNAME")
@patch("lambda_function.lambda_handler.password_obj")
@patch("lambda_function.lambda_handler.PASSWORD")
class test_login_to_api(unittest.TestCase):

    def setUp(self) -> None:
        ssm = boto3.client("ssm", "us-east-1")
        mock_values = [("/prof-svc-int/dev/api-base-url", "MY_BASE_URL"),
                       ("/prof-svc-int/dev/api-username", "MY_USERNAME"),
                       ("/prof-svc-int/dev/api-password", "MY_PASSWORD")]
        for key, val in mock_values:
            ssm.put_parameter(
                Name=key,
                Description=f"Mock value for {key}",
                Value=val,
                Type="String"
            )

    def test_my_test(self):
        # as usual
        # all parameters are now present in 'us-east-1'
        pass

Note that I've removed the mock_ssm-decorator on the test-method itself - you only need to use it on the class itself.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文