moto
moto copied to clipboard
moto v5.0+ failing to mock AWS SNS service
Description
After successfully upgrading from moto v4.x to v5.0.9 on a few of my projects, I had no problem making
the required change to mock_aws
. This allowed me to mock out AWS services such as s3, iam,
secretsmanager, ssm and dynamodb. However, trying to mock out SNS fails.
This behaviour differs from v4.2.14, which allows you to say create a SNS topic and it is returned in an ordered dict of SNS topics when sns_backend
is inspected.
Expected outcome:
Created SNS topic exists in the sns_backend
❯ poetry run pytest -s -p no:warnings
===================================================================================== test session starts ======================================================================================
configfile: pyproject.toml
collected 1 item
test_main.py sns_backend.topics = OrderedDict({'arn:aws:sns:eu-west-2:123456789012:test-topic': <moto.sns.models.Topic object at 0x104d8bfe0>})
.
====================================================================================== 1 passed in 0.92s =======================================================================================
Actual outcome
Created SNS topic not found in sns_backend
because it returns an empty OrderedDict()
.
❯ poetry run pytest -p no:warnings
===================================================================================== test session starts ======================================================================================
platform darwin -- Python 3.12.3, pytest-8.2.2, pluggy-1.5.0
configfile: pyproject.toml
collected 1 item
test_main.py F [100%]
=========================================================================================== FAILURES ===========================================================================================
______________________________________________________________________________________ test_create_topic _______________________________________________________________________________________
@mock_aws
def test_create_topic() -> None:
topic_arn = MyNotifier().create_topic(name="test-topic")
print(f"{sns_backend.topics = }")
> assert topic_arn in sns_backend.topics
E AssertionError: assert 'arn:aws:sns:eu-west-2:123456789012:test-topic' in OrderedDict()
E + where OrderedDict() = <moto.sns.models.SNSBackend object at 0x10e02de80>.topics
test_main.py:16: AssertionError
------------------------------------------------------------------------------------- Captured stdout call -------------------------------------------------------------------------------------
sns_backend.topics = OrderedDict()
=================================================================================== short test summary info ====================================================================================
FAILED test_main.py::test_create_topic - AssertionError: assert 'arn:aws:sns:eu-west-2:123456789012:test-topic' in OrderedDict()
====================================================================================== 1 failed in 0.85s =======================================================================================
Versions:
- python: 3.12
- moto: 5.0.9
- boto3: 1.34.127
How to reproduce this issue (using code snippet below):
To reproduce this issue please refer to the small code snippet below.
- In a new directory, create the files highlighted below with their code contents
- Install the dependencies (
pyproject.toml
below helps with this if you usepoetry
) - run pytest (e.g.
poetry run pytest -s
)
main.py
import boto3
AWS_REGION = "eu-west-2"
class MyNotifier:
def __init__(self) -> None:
self.client = boto3.client("sns", region_name=AWS_REGION)
def create_topic(self, name: str) -> str:
try:
return self.client.create_topic(Name=name)["TopicArn"]
except Exception as e:
raise e
test_main.py
from moto import mock_sns
from moto.core import DEFAULT_ACCOUNT_ID
from moto.sns import sns_backends
from main import AWS_REGION, MyNotifier
sns_backend = sns_backends[DEFAULT_ACCOUNT_ID][AWS_REGION]
@mock_sns
def test_create_topic() -> None:
topic_arn = MyNotifier().create_topic(name="test-topic")
print(f"{sns_backend.topics = }")
assert topic_arn in sns_backend.topics
pyproject.toml
[tool.poetry]
name = "mynotifier"
version = "0.1.0"
description = ""
readme = "README.md"
[tool.poetry.dependencies]
python = "^3.12"
boto3 = "^1.34.127"
[tool.poetry.group.dev.dependencies]
moto = "5.0.9"
pytest = "^8.2.2"
[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"