0

我习惯于pytest进行单元测试,而不使用类。今天我想尝试一下unittest,我想将我的测试封装在一个TestCase中。

然后考虑这个示例测试类:

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参数。在这里最好的方法是什么?

我问这个的原因是因为我要测试的类在初始化时需要这个参数。

4

1 回答 1

2

模拟装饰器的范围适用于该特定函数,因此在该函数中创建的数据将仅在该函数中可用。

相反,您可以使用类装饰器:

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 是一个类方法,所以在应用装饰器之前执行,它会尝试针对 AWS 本身执行该方法。

于 2021-03-27T09:16:58.310 回答