Better Programming

Advice for programmers.

Follow publication

Introduction Python’s Moto Library — Easily Mock Out AWS Services

Add more validity to your tests

Eldad Uzman
Better Programming
Published in
3 min readApr 25, 2022

Photo by Sunrise King on Unsplash

Unit tests are our first line of defense against regressive code changes.
If your Python code involves the usage of AWS resources, you might find this article useful for your testing coverage.

Resource Optimism

Resource optimism is a test smell that occurs when a test case makes an optimistic assumption about an external resource.

Either the test function itself uses an external resource, or the parts of code that it tests uses an external resource — which is not guaranteed to be available at test execution time.

The outcome of resource optimism could be flakiness in test execution, in other words, the test shows a pass or fail result when executed against the same code base.

Another problem could be the need to manage these external resources in the test setup, making it unrealistic and cumbersome.

AWS resources such as S3 buckets or sqs queues are external resources, and as such, they should be regarded as suspects for optimism.

Therefore, when running our unit tests, we want to make sure they do not depend on available AWS resources. The common practice to achieve that is mocking.

Introducing MOTO

Moto is an open source library that provides an easy abstraction to Python’s built-in unit test mock library.

Its documentation is awesome, and it supports a rich set of AWS functionalities, relieving the need to develop mocks on your own.
This way you can focus on writing your unit test to high coverage.

Hands On

Let's have a look at a simple Python class:

Project class defines a state of a project.

When initialized, it creates two resources: one is an s3 bucket; the other is the SQS queue, which also generates a client object to AWS SQS and s3 using the boto3 library.

In addition to that, it has a state, which is expressed as a UUID.

When save is called, the state changes, and the input message is stored into an s3 bucket.

When restore is called, the previously saved message is called from s3, and then a notification is sent to the SQS queue.

After that, the message is returned to the outer context.

Let's write a simple unit test:

This test is terrible as it relies on the external AWS resources, but thanks to moto, this can be easily improved with only three lines of code (lazy programmers will appreciate that :D).

First, let’s install moto from PyPI:

pip install moto

Now, let's use moto in our test code:

First, we import the s3_mock andsqs_mock from moto.

These two are decorators, and they can decorate either functions or classes, creating a mock out of all AWS resource handling calls in the decorated code block.

Now we can decorate the class TestMyAws and in all subsequent code blocks, AWS will be mocked.

In this code, we can also see that we do not need to manage secrets since all calls are mocked.

Let's run the test:

python -m unittest test/test_basic.py

Output:

.
----------------------------------------------------------------------
Ran 1 test in 1.074s
OK

A Final Note

In our init test code, we want as much isolation as possible.

However, this does not always apply to more robust tests, integration tests, API tests, regression tests, or E2E.

Sometimes, we do need to use the actual resource or to use mock servers.

Moto allows you to write stable tests and to be more concise in your test code.

Thanks for reading.

Sign up to discover human stories that deepen your understanding of the world.

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

Eldad Uzman
Eldad Uzman

Written by Eldad Uzman

Automation and RPA developer, python developer.

Responses (2)

Write a response

Oh, fantastic info! Thanks

Thanks for sharing Eldad!