pytest monkeypatch:每次调用修补方法时可以 return 不同的值吗?

pytest monkeypatch: it is possible to return different values each time when patched method called?

unittest我可以断言side_effect iterable with values - each of them one-by-one will be returned when patched method called, moreover I found that in unittest my patched method can return different results according to input arguments. Can I make something like that in pytest? Documentation没有提到这个。

你当然可以用 class 和 __call__ 属性来 monkeypatch 一些东西,它可以做任何你想做的事 - 然而,没有什么能阻止你使用 unittest.mock 和 pytest - 甚至 pytest-mock plugin 使这更容易。

您可以使用 Mock 的 side_effect 参数来设置每次调用要 returned 的内容。

side_effect: A function to be called whenever the Mock is called. See the side_effect attribute. Useful for raising exceptions or dynamically changing return values. The function is called with the same arguments as the mock, and unless it returns DEFAULT, the return value of this function is used as the return value. Alternatively side_effect can be an exception class or instance. In this case the exception will be raised when the mock is called. If side_effect is an iterable then each call to the mock will return the next value from the iterable. A side_effect can be cleared by setting it to None.

例如:

return_data = [3, 5]
test_mock = Mock(side_effect=return_data)
monkeypatch.setattr(your_module, "some_func", test_mock)

这样你第一次调用“some_func”时它将 return 3 而当你第二次调用它时它将 return 5

如果调用了两次就可以了

assert test_mock.call_count == len(return_data)

return 数据应该是可迭代的(列表、集合、元组)并且可以包含任何你想要的东西(整数、字符串、对象、元组、列表……)