Mocking Boto3 with pytest

Posted 25 July 2023 · 1 min read


When writing unit tests that interact with AWS services like S3 or DynamoDB using the boto3 Python library you'll want to mock those requests. You can use the botocore Stubber to achieve this.

Given a function that queries DynamoDB for an item:

import boto3
 
def get_item(id):
  dynamodb = boto3.client("dynamodb")
  response = dynamodb.get_item(
    TableName="item_table",
    Key={"id": id}
  )
  return response.get("Item")

You can write a pytest unit test using botocore.stub to mock the requests:

import boto3
from botocore.stub import Stubber
 
from my_project import get_item
 
def test_get_item(mocker):
  dynamodb = boto3.client("dynamodb")
  stubber = Stubber(dynamodb)
 
  stubber.add_response(
    "get_item",
    {"hello": "world"},
    {"TableName": "item_table", "Key": {"id": "hello-world"}}
  )
 
  with mocker.patch(
    "boto3.client", return_value=dynamodb
  ):
    with stubber:
      result = get_item("hello-world")
 
      assert result["hello"] == "world"
  • The add_response call adds a mock response of {"hello": "world"} for a get_item call, as well as asserting the expected arguments given
  • with stubber: activates the Stubber - you can also call stubber.activate() after setting up mock responses

You can also use the stubber with the boto3.resource API:

import boto3
 
def get_item(id):
  dynamodb = boto3.resource("dynamodb")
  table = dynamodb.Table("item_table")
  response = table.get_item(
    Key={"id": id}
  )
  return response.get("Item")
import boto3
from botocore.stub import Stubber
 
from my_project import get_item
 
def test_get_item(mocker):
  dynamodb = boto3.resource("dynamodb")
  stubber = Stubber(dynamodb.meta.client) # Access the client through `meta`
 
  stubber.add_response(
    "get_item",
    {"hello": "world"},
    {"TableName": "item_table", "Key": {"id": "hello-world"}}
  )
 
  with mocker.patch(
    "boto3.resource", return_value=dynamodb
  ):
    with stubber:
      result = get_item("hello-world")
 
      assert result["hello"] == "world"

Get new posts by email

Subscribe to get new posts to your inbox, or use the RSS feed with your own feed reader.


Related posts · browse by tag

Configure Boto3 endpoint_url

Published · 1 min read

Use environment variables to point Boto3 at local services

Python TypedDict with Generics

Published · 1 min read

How to define a Python type for a dict with generic values

Contract testing with OpenAPI & TypeScript

Published · 3 min read

Validate contracts between backend services and frontend applications