Getting Started with Moto

Installing Moto

You can use pip to install the latest released version of moto, and specify which service(s) you will use:

pip install 'moto[ec2,s3,..]'

This will install Moto, and the dependencies required for that specific service.

If you don’t care about the number of dependencies, or if you want to mock many AWS services:

pip install 'moto[all]'

If you want to install moto from source:

git clone git://github.com/getmoto/moto.git
cd moto
pip install '.[all]'

Moto usage

For example, we have the following code we want to test:

import boto3

class MyModel:
    def __init__(self, name, value):
        self.name = name
        self.value = value

    def save(self):
        s3 = boto3.client("s3", region_name="us-east-1")
        s3.put_object(Bucket="mybucket", Key=self.name, Body=self.value)

There are several ways to verify that the value will be persisted successfully.

Decorator

With a simple decorator wrapping, all calls to AWS are automatically mocked out.

import boto3
from moto import mock_aws
from mymodule import MyModel

@mock_aws
def test_my_model_save():
    conn = boto3.resource("s3", region_name="us-east-1")
    # We need to create the bucket since this is all in Moto's 'virtual' AWS account
    conn.create_bucket(Bucket="mybucket")

    model_instance = MyModel("steve", "is awesome")
    model_instance.save()

    body = conn.Object("mybucket", "steve").get()[
        "Body"].read().decode("utf-8")

    assert body == "is awesome"

Context manager

Same as the Decorator, every call inside the with statement is mocked out.

def test_my_model_save():
    with mock_aws():
        conn = boto3.resource("s3", region_name="us-east-1")
        conn.create_bucket(Bucket="mybucket")

        model_instance = MyModel("steve", "is awesome")
        model_instance.save()

        body = conn.Object("mybucket", "steve").get()[
            "Body"].read().decode("utf-8")

        assert body == "is awesome"

Raw

You can also start and stop the mocking manually.

def test_my_model_save():
    mock = mock_aws()
    mock.start()

    conn = boto3.resource("s3", region_name="us-east-1")
    conn.create_bucket(Bucket="mybucket")

    model_instance = MyModel("steve", "is awesome")
    model_instance.save()

    body = conn.Object("mybucket", "steve").get()[
        "Body"].read().decode("utf-8")

    assert body == "is awesome"

    mock.stop()

Unittest usage

If you use unittest to run tests, and you want to use moto inside setUp, you can do it with .start() and .stop() like:

import unittest
from moto import mock_aws
import boto3

def func_to_test(bucket_name, key, content):
    s3 = boto3.resource("s3")
    object = s3.Object(bucket_name, key)
    object.put(Body=content)

class MyTest(unittest.TestCase):

    bucket_name = "test-bucket"
    def setUp(self):
        self.mock_aws = mock_aws()
        self.mock_aws.start()

        # you can use boto3.client("s3") if you prefer
        s3 = boto3.resource("s3")
        bucket = s3.Bucket(self.bucket_name)
        bucket.create()

    def tearDown(self):
        self.mock_aws.stop()

    def test(self):
        content = b"abc"
        key = "/path/to/obj"

        # run the file which uploads to S3
        func_to_test(self.bucket_name, key, content)

        # check the file was uploaded as expected
        s3 = boto3.resource("s3")
        object = s3.Object(self.bucket_name, key)
        actual = object.get()["Body"].read()
        self.assertEqual(actual, content)

Class Decorator

It is also possible to use decorators on the class-level.

The decorator is effective for every test-method inside your class. State is not shared across test-methods.

@mock_aws
class TestMockClassLevel(unittest.TestCase):
    def setUp(self):
        s3 = boto3.client("s3", region_name="us-east-1")
        s3.create_bucket(Bucket="mybucket")

    def test_creating_a_bucket(self):
        # 'mybucket', created in setUp, is accessible in this test
        # Other clients can be created at will

        s3 = boto3.client("s3", region_name="us-east-1")
        s3.create_bucket(Bucket="bucket_inside")

    def test_accessing_a_bucket(self):
        # The state has been reset before this method has started
        # 'mybucket' is recreated as part of the setUp-method
        # 'bucket_inside' however, created inside the other test, no longer exists
        pass

Note

A tearDown-method can be used to destroy any buckets/state, but because state is automatically destroyed before a test-method start, this is not strictly necessary.

Stand-alone server mode

Moto also comes with a stand-alone server allowing you to mock out the AWS HTTP endpoints. This is useful if you are using any other language than Python.

$ moto_server -p3000
 * Running on http://127.0.0.1:3000/

See Non-Python SDK’s / Server Mode for more information.