Moto sns client can't call create_topic AttributeError: 'generator' object has no attribute 'create_topic'
Question:
I’m trying to follow the docs to do this:
@pytest.fixture()
def aws_credentials():
"""Mocked AWS Credentials for moto."""
os.environ["AWS_ACCESS_KEY_ID"] = "testing"
os.environ["AWS_SECRET_ACCESS_KEY"] = "testing"
os.environ["AWS_SECURITY_TOKEN"] = "testing"
os.environ["AWS_SESSION_TOKEN"] = "testing"
@pytest.fixture()
def sts(aws_credentials):
with mock_sts():
yield boto3.client("sts", region_name="us-east-1")
@pytest.fixture
def sns(aws_credentials):
with mock_sns():
yield boto3.resource("sns", region_name="us-east-1")
def test_publish(sns):
resp = sns.create_topic(Name="sdfsdfsdfsd")
I get error:
def test_publish(sns):
> topic_arn = sns.create_topic(Name="sdfsdfsdfsd")
E AttributeError: 'generator' object has no attribute 'create_topic'
Answers:
OK, I’m not 100% sure why but adding the sts decorator seems to have fixed this:
@mock_sts
def test_publish(sns):
resp = sns.create_topic(Name="sdfsdfsdfsd")
I figured that out from this article but I’m still unclear on how it works: https://www.serverlessops.io/blog/aws-lambda-serverless-development-workflow-part2-testing-debugging
Is this because boto needs to use sts so I need to mock that out too? I use a credentials file with profiles to access AWS from laptop
Edit
You also, MUST use yield to return the client. Using return here gave me an sts error. I’d like to understand this better as well. I assume I need to use yield because it’s a generator?
@pytest.fixture
def sns(aws_credentials):
with mock_sns():
# using return here causes below error
return boto3.resource("sns", region_name="us-east-1")
Error when not using yield:
botocore.exceptions.ClientError: An error occurred (InvalidClientTokenId) when calling the CreateTopic operation: The security token included in the request is invalid
I’m trying to follow the docs to do this:
@pytest.fixture()
def aws_credentials():
"""Mocked AWS Credentials for moto."""
os.environ["AWS_ACCESS_KEY_ID"] = "testing"
os.environ["AWS_SECRET_ACCESS_KEY"] = "testing"
os.environ["AWS_SECURITY_TOKEN"] = "testing"
os.environ["AWS_SESSION_TOKEN"] = "testing"
@pytest.fixture()
def sts(aws_credentials):
with mock_sts():
yield boto3.client("sts", region_name="us-east-1")
@pytest.fixture
def sns(aws_credentials):
with mock_sns():
yield boto3.resource("sns", region_name="us-east-1")
def test_publish(sns):
resp = sns.create_topic(Name="sdfsdfsdfsd")
I get error:
def test_publish(sns):
> topic_arn = sns.create_topic(Name="sdfsdfsdfsd")
E AttributeError: 'generator' object has no attribute 'create_topic'
OK, I’m not 100% sure why but adding the sts decorator seems to have fixed this:
@mock_sts
def test_publish(sns):
resp = sns.create_topic(Name="sdfsdfsdfsd")
I figured that out from this article but I’m still unclear on how it works: https://www.serverlessops.io/blog/aws-lambda-serverless-development-workflow-part2-testing-debugging
Is this because boto needs to use sts so I need to mock that out too? I use a credentials file with profiles to access AWS from laptop
Edit
You also, MUST use yield to return the client. Using return here gave me an sts error. I’d like to understand this better as well. I assume I need to use yield because it’s a generator?
@pytest.fixture
def sns(aws_credentials):
with mock_sns():
# using return here causes below error
return boto3.resource("sns", region_name="us-east-1")
Error when not using yield:
botocore.exceptions.ClientError: An error occurred (InvalidClientTokenId) when calling the CreateTopic operation: The security token included in the request is invalid