aws boto3 客户端 Stubber 帮助存根单元测试

aws boto3 client Stubber help stubbing unit tests

我正在尝试为 aws RDS 编写一些单元测试。目前,start stop rds api 调用尚未在 moto 中实现。我试过模拟 boto3 但 运行 遇到各种奇怪的问题。我用谷歌搜索了一下,发现 http://botocore.readthedocs.io/en/latest/reference/stubber.html

所以我尝试为 rds 实现示例,但代码似乎表现得像普通客户端,即使我已经对它进行了存根。不确定发生了什么或者我是否正确存根?

from LambdaRdsStartStop.lambda_function import lambda_handler
from LambdaRdsStartStop.lambda_function import AWS_REGION

def tests_turn_db_on_when_cw_event_matches_tag_value(self, mock_boto):
    client = boto3.client('rds', AWS_REGION)
    stubber = Stubber(client)
    response = {u'DBInstances': [some copy pasted real data here], extra_info_about_call: extra_info}
    stubber.add_response('describe_db_instances', response, {})

    with stubber:
        r = client.describe_db_instances()
        lambda_handler({u'AutoStart': u'10:00:00+10:00/mon'}, 'context')

因此存根内第一行的模拟工作正常,r 的值作为存根数据返回。当我尝试在我的 lambda_function.py 中进入我的 lambda_handler 方法并且仍然使用存根客户端时,它的行为就像一个普通的未存根客户端:

lambda_function.py

def lambda_handler(event, context):
    rds_client = boto3.client('rds', region_name=AWS_REGION)
    rds_instances = rds_client.describe_db_instances()

错误输出:

  File "D:\dev\projects\virtual_envs\rds_sloth\lib\site-packages\botocore\auth.py", line 340, in add_auth
    raise NoCredentialsError
NoCredentialsError: Unable to locate credentials

您需要在要测试的例程中调用 boto3 的地方修补它。此外,每次调用都会消耗 Stubber 响应,因此每个存根调用都需要另一个 add_response,如下所示:

def tests_turn_db_on_when_cw_event_matches_tag_value(self, mock_boto):
    client = boto3.client('rds', AWS_REGION)
    stubber = Stubber(client)
    # response data below should match aws documentation otherwise more errors due to botocore error handling
    response = {u'DBInstances': [{'DBInstanceIdentifier': 'rds_response1'}, {'DBInstanceIdentifierrd': 'rds_response2'}]}

    stubber.add_response('describe_db_instances', response, {})
    stubber.add_response('describe_db_instances', response, {})

    with mock.patch('lambda_handler.boto3') as mock_boto3:
        with stubber:
            r = client.describe_db_instances() # first_add_response consumed here
            mock_boto3.client.return_value = client
            response=lambda_handler({u'AutoStart': u'10:00:00+10:00/mon'}, 'context')  # second_add_response would be consumed here
            # asert.equal(r,response)