我使用botocore.stub.Stubber来模拟kmsclient。我正在使用的代码是
with botocore.stub.Stubber(s3) as stubber:
with botocore.stub.Stubber(kms) as stubber2:
stubber.add_response('copy_object', response, expectedParams)
stubber.activate()
stubber2.add_response('decrypt', response2, expectedParams2)
stubber2.activate()
handleCore(__makeValidEvent(), None, s3, kms)
stubber.assert_no_pending_responses()
stubber2.assert_no_pending_responses()
在实际实现中,kmsclient调用发生两次,导致以下异常
params = {'CiphertextBlob': b"\x01\x02\x02\x00x#\xc1\xdbp6\xe1Y\x0fS\x15\x80<\x86\xb5\xb2\x86\x9f\xaf\xa2Z\x07\xfef\x8d\xb2\xd7...\t'\xe2\xb9\x10w0\x83\xcb\xe1\xcb`\xd1\xc2\x8c\xe4\x82Q/*\xb3]\xcfZ\xb9\xbd\x1c\x9c\x96(e\x94j\x1a\x91\xba\xaeO[>\x97"}
def _assert_expected_call_order(self, model, params):
if not self._queue:
raise UnStubbedResponseError(
operation_name=model.name,
reason=(
> 'Unexpected API Call: A call was made but no additional calls expected.'
'Either the API Call was not stubbed or it was called multiple times.'
)
)
E botocore.exceptions.UnStubbedResponseError: Error getting response stub for operation Decrypt: Unexpected API Call: A call was made but no additional calls expected.Either the API Call was not stubbed or it was called multiple times.
有人可以告诉我如何在同一个对象上进行多次调用(在本例中为kmsclient)
答案 0 :(得分:1)
我通过为同一方法添加多个响应来解决此问题。
测试代码示例:
############## Test Code
client = botocore.session.get_session().create_client("cloudformation", region_name="us-east-1")
stubber = Stubber(client)
# Generate multiple responses to be returned by boto
responses = [
{
"StackId": "stack-a",
},
{
"StackId": "stack-b",
},
{
"StackId": "stack-c",
},
]
# Add each response to stubber for the same method - "update_termination_protection"
for response in responses:
stubber.add_response(
"update_termination_protection",
response,
)
stubber.activate()
actual = method_to_test(client, data)
stubber.deactivate()
assert actual == True
示例测试方法:
############## Real method
def method_to_test(self, client, data):
for item in data:
client.update_termination_protection(
EnableTerminationProtection=True,
StackName=item,
)
return True
这有效并且不会引发异常。
答案 1 :(得分:0)
我遇到了同样的问题,但是发现我可以在设置存根之前通过调用deactivate()来解决它。
因此,您的示例将是:
with botocore.stub.Stubber(s3) as stubber:
with botocore.stub.Stubber(kms) as stubber2:
stubber.deactivate()
stubber.add_response('copy_object', response, expectedParams)
stubber.activate()
stubber2.deactivate()
stubber2.add_response('decrypt', response2, expectedParams2)
stubber2.activate()
handleCore(__makeValidEvent(), None, s3, kms)
stubber.assert_no_pending_responses()
stubber2.assert_no_pending_responses()
答案 2 :(得分:0)
根据Stubber.add_response() documentation:
<块引用>向响应队列添加服务响应。
因此,如果您希望多次调用一个存根方法,那么您的测试应该多次调用 add_response(),每次都按照应使用的顺序提供响应和预期参数。
因此,两次调用 kms.decrypt 的测试代码将按如下方式排列:
stubber.add_response('copy_object', response, expectedParams)
stubber2.add_response('decrypt', response2, expectedParams2)
stubber2.add_response('decrypt', response2, expectedParams2)
with botocore.stub.Stubber(s3) as stubber:
with botocore.stub.Stubber(kms) as stubber2:
handleCore(__makeValidEvent(), None, s3, kms)
stubber.assert_no_pending_responses()
stubber2.assert_no_pending_responses()
如果第一次和第二次调用 kms.decrypt 做不同的事情,您可能最终会使用 response2、expectedParams2 和 response3、expectedParams3。