python - 如何在测试用例中模拟 uuid 生成?

标签 python iterator mocking python-unittest

我有一个测试用例,在其中的设置中,我创建了一个对象,我想为其模拟模块 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/

相关文章:

python - 如果我已经了解 Python 3,我该如何学习 Python 2?

java - 链接列表 : Iterator vs List Iterator

c++ - 使用 std::tuple 从 map 中输出

unit-testing - 在Kotlin中模拟http响应

python - 如何通过网络连接到 Rabbit-MQ 服务器?

python - 收到 KeyError : '0_0' for my python program

python - urllib2加载移动站点的问题

c++ - char[] 乱七八糟的输出

ruby - RSpec 模拟 :each block

unit-testing - 将模拟 DOM 事件传递给没有 jQuery 的指令处理程序