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

时间:2017-08-10 04:25:27

标签: python-2.7 boto boto3

我正在尝试为aws RDS编写一些单元测试。目前,启动停止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')

因此,对于stubber中第一行的模拟WORKS和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

1 个答案:

答案 0 :(得分:3)

您将需要修补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)