Python 使用 MOTO 模拟 SSM

Python mocking using MOTO for SSM

取自这个答案:

我现在有这个代码:

test_2.py

from unittest import TestCase

import boto3
import pytest
from moto import mock_ssm


@pytest.yield_fixture
def s3ssm():
    with mock_ssm():
        ssm = boto3.client("ssm")
        yield ssm


@mock_ssm
class MyTest(TestCase):
    def setUp(self):
        ssm = boto3.client("ssm")
        ssm.put_parameter(
            Name="/mypath/password",
            Description="A test parameter",
            Value="this is it!",
            Type="SecureString",
        )

    def test_param_getting(self):
        import real_code

        resp = real_code.get_variable("/mypath/password")
        assert resp["Parameter"]["Value"] == "this is it!"

这是我要测试的代码(或简化示例):

real_code.py

import boto3


class ParamTest:
    def __init__(self) -> None:
        self.client = boto3.client("ssm")
        pass

    def get_parameters(self, param_name):
        print(self.client.describe_parameters())
        return self.client.get_parameters_by_path(Path=param_name)


def get_variable(param_name):
    p = ParamTest()
    param_details = p.get_parameters(param_name)

    return param_details

我尝试了很多解决方案,在pytest和unittest之间切换了好几次!

每次我 运行 代码,它都没有到达 AWS,所以似乎有什么影响了 boto3 客户端,但它没有 return 参数。如果我编辑 real_code.py 使其内部没有 class,则测试通过。

real_code.py文件中class里面的客户端不能打补丁吗?如果可能的话,我试图在不编辑 real_code.py 文件的情况下执行此操作。

谢谢,

get_parameters_by_path return 以提供的路径为前缀的所有参数。
当提供 /mypath 时,它会 return /mypath/password.
但是在提供 /mypath/password 时,如您的示例所示,它只会 return 如下所示的参数:/mypath/password/..

如果您只想检索单个参数,get_parameter 调用会更合适:

class ParamTest:
    def __init__(self) -> None:
        self.client = boto3.client("ssm")
        pass

    def get_parameters(self, param_name):
        # Decrypt the value, as it is stored as a SecureString
        return self.client.get_parameter(Name=param_name, WithDecryption=True)

编辑:请注意,Moto 在这方面的行为与 AWS 相同。 来自 https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/ssm.html#SSM.Client.get_parameters_by_path:

[The Path-parameter is t]he hierarchy for the parameter. [...] The hierachy is the parameter name except the last part of the parameter. For the API call to succeeed, the last part of the parameter name can't be in the path.