Simple Boto3 mock in Python with Pytest monkeypatch

If you’re anything like me, then you might find mocking dependencies in Python tests quite fiddly and unintuitive (it’s certainly less straightforward than Jest in TypeScript).

I needed to mock one part of the Python boto3 library for AWS, and I got it working using Pytest’s monkeypatch.

This shows a test for fetching a value from a JSON-encoded secret string in AWS Secrets Manager, but you can extrapolate from this roughly how to mock out other boto3 APIs in a similar way.

import json

import pytest
import boto3

from src.foobar import foobar

TEST_AWS_REGION = "test-region-1"
TEST_SECRET_NAME = "foobar-secret-name"
TEST_SECRET_VALUE = "foobar-secret-value"



class MockBoto3Client:
  # noinspection PyPep8Naming
  @staticmethod
  def get_secret_value(SecretId: str):
    assert SecretId == TEST_SECRET_NAME
    return {
      "SecretString": json_util.dumps(
        {
          "key": TEST_SECRET_VALUE,
        }
      )
    }


class MockBoto3Session:
  @staticmethod
  def client(service_name: str, region_name: str):
    assert service_name == "secretsmanager"
    assert region_name == TEST_AWS_REGION
    return MockBoto3Client


@pytest.fixture
def mock_boto3(monkeypatch: pytest.MonkeyPatch):
  monkeypatch.setattr("src.foobar.SECRET_NAME", TEST_SECRET_NAME)
  monkeypatch.setattr(boto3.session, "Session", MockBoto3Session)


def test_docdb_host(mock_boto3):
    assert foobar() == TEST_SECRET_VALUE

Tech mentioned