2

我正在为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 发出请求?

4

2 回答 2

1

查看moto 的 README.md for boto/boto3,我注意到 S3 连接代码,有备注

# 我们需要创建存储桶,因为这都在 Moto 的“虚拟”AWS 账户中

如果我是正确的,显示的错误不是 AWS 错误,而是 Moto 错误。您需要将要模拟的所有模拟资源初始化到 Moto 虚拟空间。这意味着,您需要使用另一个脚本来使用 moto 模拟“create_instance”,然后才能启动实例。

于 2017-10-20T14:04:42.467 回答
0

因此,在联系了一些贡献者后,我被告知:

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然后我可以用它来进一步测试。希望这可以帮助那些在未来某个时候偶然发现这一点的人。

于 2017-10-20T15:21:22.713 回答