Python 模拟:如何根据输入值更改行为?

Python mocking: how do I change behavior based on input values?

我有一个 class,我正试图用 python 中的测试覆盖它。

我有一个正在注入 class 的依赖项。

class UnderTest:
    def __init__(self, dependency):
        self.dependency = dependency

我不太关心这里依赖的内部结构,而是想模拟它。

所以我在测试中实例化 class,注入依赖项:

dependency = MagicMock()
dependency.some_func = MagicMock(return_value='blue')
under_test = UnderTest(dependency)

稍后当我想测试 class UnderTest 时,我希望依赖项根据传递给它的参数 return 不同的值。所以在被测代码中,我可能有类似

的东西
value = dependency.some_func('a')

但我还希望在使用不同的值调用时依赖于 return 其他内容。

value = dependency.some_func('b')

理想情况下(我在其他框架中看到过),我可以将模拟配置为 return 不同的值,例如(我希望它如何工作)

dependency.some_func = MagicMock([
    {'called_with': 'a', 'return_value': 'blue'}, 
    {'called_with': 'b', 'return_value': 'green'}
])

您可以使用 side_effect 属性设置一个可调用对象,根据其参数设置 return 不同的值。

results = {'a': 'blue', 'b': 'green'}
dependency.some_func = MagicMock(side_effect=lambda arg: results.get(arg, DEFAULT))

DEFAULT singleton 用于表示正常模拟 return 值用于不在字典中的参数。)