【问题标题】:aws boto3 client Stubber help stubbing unit testsaws boto3 客户端 Stubber 帮助存根单元测试
【发布时间】:2017-08-18 12:05:42
【问题描述】:

我正在尝试为 aws RDS 编写一些单元测试。目前,moto 中尚未实现 start stop rds api 调用。我试着嘲笑 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')

因此,存根内第一行的模拟 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

【问题讨论】:

  • stubber 与典型模拟相比的优势在于,它的行为几乎与客户端完全一样,减去了实际的 http 请求。因此,您仍需要使用凭据设置客户端并配置区域,否则会出现类似错误。
  • 嗨,Jordon,我想你可能误读了我的帖子。模拟在我的测试中有效,直到我尝试在另一个文件中初始化客户端 -> lambda_function.py
  • 您似乎没有将存根客户端传递给您的 lambda 处理程序。
  • 不,伙计,我无意将存根客户端传递给任何东西。我正在尝试使用存根客户端“覆盖” lamnda_function.py 中的真实客户端,以便我可以运行一些单元测试。与 moto 或 python mock 类似
  • 你是对的,我可以将客户端传递给 lambda_handler 但这似乎是一种 hacky 方式。如果有人对更清洁的方式有任何建议,那就太好了

标签: python-2.7 boto boto3


【解决方案1】:

您需要在您将要测试的例程中调用它的地方修补 boto3。此外,每次调用似乎都会消耗存根响应,因此每个存根调用都需要另一个 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)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-09-02
    • 2021-02-06
    • 1970-01-01
    • 2013-12-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多