我有一个测试用例,其中在setUp中,我创建了一个对象,我想在模块uuid4
中模拟函数uuid
。
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
我现在的问题是,当我运行写两个测试用例时,第二次创建对象时,它会第一次获得其他uuids。因此,结果取决于我的测试类中的测试用例的数量以及它们的运行顺序,这是我不想要的。
答案 0 :(得分:3)
答案比我想象的要容易:只是不要使用迭代器!相反,将uuids列表设置为模拟的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
修改强>
我找到了一种更好的方法将其写为上下文管理器,它允许根据上下文为uuids添加前缀。
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
说明:我正在使用uuid.uuid4
模拟函数patch.object(uuid, 'uuid4')
。在其中,我将副作用定义为列表。如果你的副作用是一个列表,它可以看作是后续调用中该函数的返回值列表,所以第一次调用函数uuid4()
时,它返回该列表的第一个元素,第二个时间第二个元素等。如果在with-context中我生成了10个对象A,则UUID将为'obj_a_uuid_0'
,最多为'obj_a_uuid_9'
。
答案 1 :(得分:1)
我找到了一个更好的解决方案:
TEST_UUIDS_COUNT = 0
def mock_uuid():
global TEST_UUIDS_COUNT
TEST_UUIDS_COUNT += 1
return uuid.UUID(int=TEST_UUIDS_COUNT)
class MyTestCase(TestCase):
def setUp(self, **kwargs):
self._create_my_object
@patch('uuid.uuid4', mock_uuid)
def _create_my_object(self):
# Create an object using a uuid
这样,它是通用的,并且适用于所有边缘情况。