使用 moto 的 SNS 模拟无法正常工作
SNS mocking with moto is not working correctly
在我的单元测试中:
def test_my_function_that_publishes_to_sns():
conn = boto3.client("sns", region_name="us-east-1")
mock_topic = conn.create_topic(Name="mock-topic")
topic_arn = mock_topic.get("TopicArn")
os.environ["SNS_TOPIC"] = topic_arn
# call my_function
my_module.my_method()
正在测试的功能
# inside my_module, my_function...
sns_client.publish(
TopicArn=os.environ["SNS_TOPIC"], Message="my message",
)
我收到错误:botocore.errorfactory.NotFoundException: An error occurred (NotFound) when calling the Publish operation: Endpoint with arn arn:aws:sns:us-east-1:123456789012:mock-topic not found
没有意义,这是 moto 应该创建和嘲笑的主题。为什么说它不存在?如果我在单元测试本身内部调用 conn.publish(TopicArn=topic_arn, Message="sdfsdsdf")
它似乎是在模拟它,但它不会为单元测试执行的 my_module.my_method() 模拟它。也许它过早地破坏了嘲笑话题?
编辑我尝试了各种方法,但我得到了完全相同的错误:
# Using context manager
def test_my_function_that_publishes_to_sns():
with mock_sns():
conn = boto3.client("sns", region_name="us-east-1")
mock_topic = conn.create_topic(Name="mocktopic")
topic_arn = mock_topic.get("TopicArn")
os.environ["SNS_TOPIC"] = topic_arn
# call my_function
my_module.my_method()
# Using decorator
@mock_sns
def test_my_function_that_publishes_to_sns():
conn = boto3.client("sns", region_name="us-east-1")
mock_topic = conn.create_topic(Name="mocktopic")
topic_arn = mock_topic.get("TopicArn")
os.environ["SNS_TOPIC"] = topic_arn
# call my_function
my_module.my_method()
# Using decorator and context manager
@mock_sns
def test_my_function_that_publishes_to_sns():
with mock_sns():
conn = boto3.client("sns", region_name="us-east-1")
mock_topic = conn.create_topic(Name="mocktopic")
topic_arn = mock_topic.get("TopicArn")
os.environ["SNS_TOPIC"] = topic_arn
# call my_function
my_module.my_method()
也打开了 GitHub 问题:https://github.com/spulec/moto/issues/3027
问题是 my_module.my_method() 没有设置区域只是 client = boto3.client("sns")
它找不到它,因为它默认为与硬编码到单元测试中的 us-east-1 不同的区域
也许对你有帮助
将所有模块保持在一个 class 中,并在 class 上放置一个装饰器 @mock_sns 来模拟 sns,还将装饰器 @mock_sns 放在你正在初始化的函数上你连接到sns。
示例:
@mock_sns
class TestSnsMock(unittest.TestCase):
@classmethod
@mock_sns
def setUpClass(cls):
cls.conn = boto3.client("sns", region_name="us-east-1")
cls.conn.create_topic(Name="some-topic")
cls.response = cls.conn.list_topics()
cls.topic_arn = cls.response["Topics"][0]["TopicArn"]
def test_publish_sns(self):
message = "here is same message"
self.sns_client.publish(TopicArn=self.topic_arn, Message=message)
if __name__ == "__main__":
unittest.main()
在我的单元测试中:
def test_my_function_that_publishes_to_sns():
conn = boto3.client("sns", region_name="us-east-1")
mock_topic = conn.create_topic(Name="mock-topic")
topic_arn = mock_topic.get("TopicArn")
os.environ["SNS_TOPIC"] = topic_arn
# call my_function
my_module.my_method()
正在测试的功能
# inside my_module, my_function...
sns_client.publish(
TopicArn=os.environ["SNS_TOPIC"], Message="my message",
)
我收到错误:botocore.errorfactory.NotFoundException: An error occurred (NotFound) when calling the Publish operation: Endpoint with arn arn:aws:sns:us-east-1:123456789012:mock-topic not found
没有意义,这是 moto 应该创建和嘲笑的主题。为什么说它不存在?如果我在单元测试本身内部调用 conn.publish(TopicArn=topic_arn, Message="sdfsdsdf")
它似乎是在模拟它,但它不会为单元测试执行的 my_module.my_method() 模拟它。也许它过早地破坏了嘲笑话题?
编辑我尝试了各种方法,但我得到了完全相同的错误:
# Using context manager
def test_my_function_that_publishes_to_sns():
with mock_sns():
conn = boto3.client("sns", region_name="us-east-1")
mock_topic = conn.create_topic(Name="mocktopic")
topic_arn = mock_topic.get("TopicArn")
os.environ["SNS_TOPIC"] = topic_arn
# call my_function
my_module.my_method()
# Using decorator
@mock_sns
def test_my_function_that_publishes_to_sns():
conn = boto3.client("sns", region_name="us-east-1")
mock_topic = conn.create_topic(Name="mocktopic")
topic_arn = mock_topic.get("TopicArn")
os.environ["SNS_TOPIC"] = topic_arn
# call my_function
my_module.my_method()
# Using decorator and context manager
@mock_sns
def test_my_function_that_publishes_to_sns():
with mock_sns():
conn = boto3.client("sns", region_name="us-east-1")
mock_topic = conn.create_topic(Name="mocktopic")
topic_arn = mock_topic.get("TopicArn")
os.environ["SNS_TOPIC"] = topic_arn
# call my_function
my_module.my_method()
也打开了 GitHub 问题:https://github.com/spulec/moto/issues/3027
问题是 my_module.my_method() 没有设置区域只是 client = boto3.client("sns")
它找不到它,因为它默认为与硬编码到单元测试中的 us-east-1 不同的区域
也许对你有帮助
将所有模块保持在一个 class 中,并在 class 上放置一个装饰器 @mock_sns 来模拟 sns,还将装饰器 @mock_sns 放在你正在初始化的函数上你连接到sns。
示例:
@mock_sns
class TestSnsMock(unittest.TestCase):
@classmethod
@mock_sns
def setUpClass(cls):
cls.conn = boto3.client("sns", region_name="us-east-1")
cls.conn.create_topic(Name="some-topic")
cls.response = cls.conn.list_topics()
cls.topic_arn = cls.response["Topics"][0]["TopicArn"]
def test_publish_sns(self):
message = "here is same message"
self.sns_client.publish(TopicArn=self.topic_arn, Message=message)
if __name__ == "__main__":
unittest.main()