使用 unittests 和 moto 模拟 AWS
Using unittests and moto to mock AWS
我习惯于 pytest
单元测试方法,而不使用 classes。今天我想尝试 unittest
并且我想将我的测试封装在 TestCase.
中
然后考虑这个样本测试class:
import unittest
import moto
import boto3
class TestMyClass(unittest.TestCase):
@classmethod
@moto.mock_ssm
def setUpClass(cls) -> None:
cls.ssm_client = boto3.client('ssm')
cls.ssm_client.put_parameter(Name='test', Value='foo', Type='String')
@moto.mock_ssm
def test_something(self):
value = self.ssm_client.get_parameter(Name='test').get('Parameter').get('Value')
self.assertEqual(value, 'foo')
为什么放置在 setUpClass
中的参数在测试中不可见?我可以想象,通过在那里使用 @moto.mock_ssm
装饰器,一切都将在模拟上下文中完成。
但是,我可以将参数放在 test_something
中,就像:
@moto.mock_ssm
def test_something(self):
self.ssm_client.put_parameter(Name='test', Value='foo', Type='String')
value = self.ssm_client.get_parameter(Name='test').get('Parameter').get('Value')
self.assertEqual(value, 'foo')
然后它(显然)起作用了。为什么不采用我的第一种方法?我不想为每个依赖它的测试填充伪造的 ssm 参数。这样做的最佳方式是什么?
我之所以这么问是因为我要测试的class初始化的时候需要这个参数
模拟装饰器的范围适用于该特定函数,因此在该函数内创建的数据将仅在该函数内可用。
相反,您可以使用 class-装饰器:
import unittest
import moto
import boto3
@moto.mock_ssm
class TestMyClass(unittest.TestCase):
client = None
def setUp(self) -> None:
self.client = boto3.client('ssm')
self.client.put_parameter(Name='test', Value='foo', Type='String')
def test_something(self):
value = self.client.get_parameter(Name='test').get('Parameter').get('Value')
self.assertEqual(value, 'foo')
请注意,我已切换到 setUp
,而不是 setUpClass
。因为 setUpClass 是一个 class 方法,它在应用装饰器之前执行,它会尝试对 AWS 本身执行此方法。
我习惯于 pytest
单元测试方法,而不使用 classes。今天我想尝试 unittest
并且我想将我的测试封装在 TestCase.
然后考虑这个样本测试class:
import unittest
import moto
import boto3
class TestMyClass(unittest.TestCase):
@classmethod
@moto.mock_ssm
def setUpClass(cls) -> None:
cls.ssm_client = boto3.client('ssm')
cls.ssm_client.put_parameter(Name='test', Value='foo', Type='String')
@moto.mock_ssm
def test_something(self):
value = self.ssm_client.get_parameter(Name='test').get('Parameter').get('Value')
self.assertEqual(value, 'foo')
为什么放置在 setUpClass
中的参数在测试中不可见?我可以想象,通过在那里使用 @moto.mock_ssm
装饰器,一切都将在模拟上下文中完成。
但是,我可以将参数放在 test_something
中,就像:
@moto.mock_ssm
def test_something(self):
self.ssm_client.put_parameter(Name='test', Value='foo', Type='String')
value = self.ssm_client.get_parameter(Name='test').get('Parameter').get('Value')
self.assertEqual(value, 'foo')
然后它(显然)起作用了。为什么不采用我的第一种方法?我不想为每个依赖它的测试填充伪造的 ssm 参数。这样做的最佳方式是什么?
我之所以这么问是因为我要测试的class初始化的时候需要这个参数
模拟装饰器的范围适用于该特定函数,因此在该函数内创建的数据将仅在该函数内可用。
相反,您可以使用 class-装饰器:
import unittest
import moto
import boto3
@moto.mock_ssm
class TestMyClass(unittest.TestCase):
client = None
def setUp(self) -> None:
self.client = boto3.client('ssm')
self.client.put_parameter(Name='test', Value='foo', Type='String')
def test_something(self):
value = self.client.get_parameter(Name='test').get('Parameter').get('Value')
self.assertEqual(value, 'foo')
请注意,我已切换到 setUp
,而不是 setUpClass
。因为 setUpClass 是一个 class 方法,它在应用装饰器之前执行,它会尝试对 AWS 本身执行此方法。