Search code examples
pythonboto3moto

Mocking boto3 calls actual boto3


I'm writing some test for boto3 functions and using the moto library to mock boto3.

The example they provide is as such:

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'

However when I try something similar, using a trivial example here, by doing this:

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

Why is it actually making request to AWS when I clearly have the function wrapped in the mocker?


Solution

  • Looking at the README.md of moto for boto/boto3, I notice on the S3 connection code, there is a remarks

    # We need to create the bucket since this is all in Moto's 'virtual' AWS account

    If I am correct, the error shown is not AWS error, but Moto error. You need to initialise all the mock resources you want to mock to the Moto virtual space. This mean, you need to use another script to use moto to mock "create_instance" before you can start the instance.