我可以在模拟中使用 side_effect 来提供无限数量的值吗?

Can I use side_effect in my mocking to provide an indefinite number of values?

所以我可以在 python 模拟中使用带有 side_effect 的可迭代来生成我对模拟的调用返回的变化值:

some_mock.side_effect = [1, 2, 3]

return_value 每次都提供相同的值

some_mock.return_value = 8

有没有一种方法可以使用这些方法中的一个或两个,以便模拟生成一些预定值开始,然后在第一组用完时对一个特定值进行无限响应?即:

[1, 2, 3, 8, 8, 8, 8, 8, 8, 等等等等]

没有特定的内置功能可以执行此操作,但您可以通过添加执行此操作的副作用来实现。

在我能想到的情况下,只需添加一些最需要的值而不是无穷大的值就足够了,并使用带有列表的 side_effect 版本:

side_effect = [1, 2, 3] + [8] * 100
my_mock.side_effect = side_effect

如果您真的需要无限数量的响应,您可以使用 side_effect 的另一个版本,它使用函数对象而不是列表。你需要一些生成器函数来创建你的无限列表,并在你的函数中迭代它,记住当前位置。这是一个示例实现(使用 class 来避免全局变量):

from itertools import repeat

class SideEffect:
    def __init__(self):
        self.it = self.generator()  # holds the current iterator

    @staticmethod
    def generator():
        yield from range(1, 4)  # yields 1, 2, 3
        yield from repeat(8)  # yields 8 infinitely

    def side_effect(self, *args, **kwargs):
        return next(self.it)

...
my_mock.side_effect = SideEffect().side_effect

这应该有想要的效果。