当 python mock 同时具有 return 值和副作用列表时会发生什么?
What happens when a python mock has both a return value and a list of side effects?
我无法理解某些测试代码中发生的事情。它看起来像这样:
import pytest
from unittest.mock import MagicMock
from my_module import MyClass
confusing_mock = MagicMock(
return_value=b"",
side_effect=[
ConnectionError(),
b"another_return_value?",
b"another_another_return_value?"
])
mocked_class = MyClass()
monkeypatch.setattr(mocked_class, "method_to_call_thrice", confusing_mock)
我知道:
side_effect
是调用 mock 时调用的函数
- 但是如果
side_effect
是一个可迭代对象,那么“每次调用 mock 都会
return iterable 的下一个值”(感谢 pytest
文档)
- 文档还说如果函数传递给
side_effect
returns DEFAULT
,然后模拟将 return 它的正常值来自
return_value
但这是我不明白的:
- 当我提供两者一个副作用列表和一个
return值?
- 每次调用
MyClass.method_to_call_thrice
时我应该看到什么?
使用 side_effect
。列表值可以包含 mock.DEFAULT
,函数可以包含 return mock.DEFAULT
,以指示使用 return_value
属性的值。
>>> import unittest.mock
>>> m = unittest.mock.Mock(return_value="foo",
... side_effect=[1, 2, unittest.mock.DEFAULT, 4, 5])
>>> m()
1
>>> m()
2
>>> m()
'foo'
>>> m()
4
>>> m()
5
>>> unittest.mock.Mock(return_value="foo",
... side_effect=lambda: unittest.mock.DEFAULT)()
'foo'
我无法理解某些测试代码中发生的事情。它看起来像这样:
import pytest
from unittest.mock import MagicMock
from my_module import MyClass
confusing_mock = MagicMock(
return_value=b"",
side_effect=[
ConnectionError(),
b"another_return_value?",
b"another_another_return_value?"
])
mocked_class = MyClass()
monkeypatch.setattr(mocked_class, "method_to_call_thrice", confusing_mock)
我知道:
side_effect
是调用 mock 时调用的函数- 但是如果
side_effect
是一个可迭代对象,那么“每次调用 mock 都会 return iterable 的下一个值”(感谢 pytest 文档) - 文档还说如果函数传递给
side_effect
returnsDEFAULT
,然后模拟将 return 它的正常值来自return_value
但这是我不明白的:
- 当我提供两者一个副作用列表和一个 return值?
- 每次调用
MyClass.method_to_call_thrice
时我应该看到什么?
side_effect
。列表值可以包含 mock.DEFAULT
,函数可以包含 return mock.DEFAULT
,以指示使用 return_value
属性的值。
>>> import unittest.mock
>>> m = unittest.mock.Mock(return_value="foo",
... side_effect=[1, 2, unittest.mock.DEFAULT, 4, 5])
>>> m()
1
>>> m()
2
>>> m()
'foo'
>>> m()
4
>>> m()
5
>>> unittest.mock.Mock(return_value="foo",
... side_effect=lambda: unittest.mock.DEFAULT)()
'foo'