模拟 boto3 调用实际的 boto3
Mocking boto3 calls actual boto3
我正在为 boto3
函数编写一些测试并使用 moto
库来模拟 boto3
。
他们提供的例子是这样的:
import boto3
from moto import mock_ec2
def add_servers(ami_id, count):
client = boto3.client('ec2', region_name='us-west-1')
client.run_instances(ImageId=ami_id, MinCount=count, MaxCount=count)
@mock_ec2
def test_add_servers():
add_servers('ami-1234abcd', 2)
client = boto3.client('ec2', region_name='us-west-1')
instances = client.describe_instances()['Reservations'][0]['Instances']
assert len(instances) == 2
instance1 = instances[0]
assert instance1['ImageId'] == 'ami-1234abcd'
然而,当我尝试类似的事情时,在这里使用一个简单的例子,通过这样做:
def start_instance(instance_id):
client = boto3.client('ec2')
client.start_instances(InstanceIds=[instance_id])
@mock_ec2
def test_start_instance():
start_instance('abc123')
client = boto3.client('ec2')
instances = client.describe_instances()
print instances
test_start_instance()
ClientError: An error occurred (InvalidInstanceID.NotFound) when calling the StartInstances operation: The instance ID '[u'abc123']' does not exist
当我明明已经将函数包装在模拟程序中时,为什么它实际上向 AWS 发出请求?
查看 moto for boto/boto3 的 README.md,我注意到
在S3连接代码上,有一个备注
# We need to create the bucket since this is all in Moto's 'virtual'
AWS account
如果我没猜错,显示的错误不是 AWS 错误,而是 Moto 错误。您需要将要模拟的所有模拟资源初始化为 Moto 虚拟 space。这意味着,您需要使用另一个脚本来使用 moto 模拟 "create_instance" 才能启动实例。
所以在联系了一些贡献者后,我被告知:
Moto isn't like a MagicMock--it's an actual in-memory representation of the AWS resources. So you can't start an instance you haven't created, you can't create an instance in a vpc you haven't previously defined in Moto, etc.
为了使用需要特定资源的服务,您首先必须创建该模拟服务。为了让我的功能正常工作,我继续模拟了对 create_instance
的调用,然后我可以用它来进一步测试。希望这对那些在未来某个时候偶然发现这个问题的人有所帮助。
我正在为 boto3
函数编写一些测试并使用 moto
库来模拟 boto3
。
他们提供的例子是这样的:
import boto3
from moto import mock_ec2
def add_servers(ami_id, count):
client = boto3.client('ec2', region_name='us-west-1')
client.run_instances(ImageId=ami_id, MinCount=count, MaxCount=count)
@mock_ec2
def test_add_servers():
add_servers('ami-1234abcd', 2)
client = boto3.client('ec2', region_name='us-west-1')
instances = client.describe_instances()['Reservations'][0]['Instances']
assert len(instances) == 2
instance1 = instances[0]
assert instance1['ImageId'] == 'ami-1234abcd'
然而,当我尝试类似的事情时,在这里使用一个简单的例子,通过这样做:
def start_instance(instance_id):
client = boto3.client('ec2')
client.start_instances(InstanceIds=[instance_id])
@mock_ec2
def test_start_instance():
start_instance('abc123')
client = boto3.client('ec2')
instances = client.describe_instances()
print instances
test_start_instance()
ClientError: An error occurred (InvalidInstanceID.NotFound) when calling the StartInstances operation: The instance ID '[u'abc123']' does not exist
当我明明已经将函数包装在模拟程序中时,为什么它实际上向 AWS 发出请求?
查看 moto for boto/boto3 的 README.md,我注意到 在S3连接代码上,有一个备注
# We need to create the bucket since this is all in Moto's 'virtual' AWS account
如果我没猜错,显示的错误不是 AWS 错误,而是 Moto 错误。您需要将要模拟的所有模拟资源初始化为 Moto 虚拟 space。这意味着,您需要使用另一个脚本来使用 moto 模拟 "create_instance" 才能启动实例。
所以在联系了一些贡献者后,我被告知:
Moto isn't like a MagicMock--it's an actual in-memory representation of the AWS resources. So you can't start an instance you haven't created, you can't create an instance in a vpc you haven't previously defined in Moto, etc.
为了使用需要特定资源的服务,您首先必须创建该模拟服务。为了让我的功能正常工作,我继续模拟了对 create_instance
的调用,然后我可以用它来进一步测试。希望这对那些在未来某个时候偶然发现这个问题的人有所帮助。