moto icon indicating copy to clipboard operation
moto copied to clipboard

moto v5.0+ failing to mock AWS SNS service

Open wunzeco opened this issue 8 months ago • 2 comments

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.

  1. In a new directory, create the files highlighted below with their code contents
  2. Install the dependencies (pyproject.toml below helps with this if you use poetry)
  3. 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"

wunzeco avatar Jun 19 '24 09:06 wunzeco