我正在尝试为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
答案 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)