我有一个测试用例,在其中的设置中,我创建了一个对象,我想为其模拟模块 uuid
中的函数 uuid4
。
TEST_UUIDS = ['uuid_{}'.format(i) for i in range(10000)]
UUID_POOL = iter(TEST_UUIDS)
def generate_uuid() -> str:
return next(UUID_POOL)
class MyTestCase(TestCase):
def setUp(self, **kwargs):
self._create_my_object
@patch.object(uuid, 'uuid4', generate_uuid)
def _create_my_object(self):
# Create an object using a uuid
我现在的问题是,当我运行编写两个测试用例时,第二次创建对象时,它会像第一次一样获得其他 uuid。因此,结果取决于我的测试类中测试用例的数量和它们运行的顺序,这是我不想要的。
- 这是模拟 uuid 生成器的最佳方式吗?
- 如何在每次调用 setUp(或 tearDown)时重置或重新创建迭代器?
最佳答案
答案比我想象的要简单:只是不要使用迭代器!相反,将 uuid 列表设置为模拟的 side_effect
。
TEST_UUIDS = ['uuid_{}'.format(i) for i in range(10000)]
class MyTestCase(TestCase):
def setUp(self, **kwargs):
self._create_my_object
@patch.object(uuid, 'uuid4', side_effect=TEST_UUIDS)
def _create_my_object(self):
# Create an object using a uuid
编辑
我发现了一种更好的方式来将其编写为上下文管理器,它允许根据上下文为 uuid 添加前缀。
TEST_UUIDS = ['uuid_{}'.format(i) for i in range(10000)]
def uuid_prefix(prefix: str):
return patch.object(uuid, 'uuid4', side_effect=['{}_{}'.format(prefix, x) for x in TEST_UUIDS])
class MyTestCase(TestCase):
def setUp(self, **kwargs):
self._create_my_object
def _create_my_object(self):
with uuid_prefix('obj_a'):
# Create an object A using a uuid
with uuid_prefix('obj_b'):
# Create an object B using a uuid
说明:我正在使用 patch.object(uuid, 'uuid4')
模拟函数 uuid.uuid4
。在其中,我将副作用定义为列表。如果你的副作用是一个列表,它可以被看作是该函数在后续调用中的返回值列表,所以第一次调用函数 uuid4()
时,它返回的第一个元素该列表,第二次是第二个元素,等等。如果在 with-context 中我生成 10 个对象 A,UUID 将是 'obj_a_uuid_0'
到 'obj_a_uuid_9'
.
关于python - 如何在测试用例中模拟 uuid 生成?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44395755/