模拟对象库 ANY 没有按预期工作
mock object library ANY not working as expected
我目前正在尝试模拟对服务器的补丁请求,并且我正在尝试使用模拟对象库中的 ANY 属性。我有以下代码:
@patch('path_to_patch.patch')
def test_job_restarted_succesfully(mock_patch):
make_patch_call()
mock_patch.assert_called_with(url=ANY, payload=ANY, callback=ANY, async_run=ANY, kwargs=ANY)
我收到以下错误:
AssertionError: Expected call: patch(async_run=<ANY>, callback=<ANY>, kwargs=<ANY>, payload=<ANY>, url=<ANY>)
E Actual call: patch(async_run=True, callback=<function JobSvc.send_job_patch_request.<locals>.retry_on_404 at 0x000002752B873168>, payload={'analyzer': {'state': 'started'}, 'meta': {}}, svc_auth=UUID('40ed1a00-a51f-11eb-b1ed-b46bfc345269'), url='http://127.0.0.1:8080/rarecyte/1.0/jobs/slide1@20210422_203831_955885')
我在下面给出的文档中找到了 ANY,但无法弄清楚为什么 assert_called_once_with() 需要调用的实际参数。
这是文档中的相关部分:https://docs.python.org/3/library/unittest.mock.html#any
编辑:
make_patch_call() 在计算出补丁函数所需的所有参数后最终调用此补丁函数。
def patch(self, url, payload, callback=None, async_run=False, **kwargs):
payload = self._serialize_payload(payload)
func = self._do_async_request if async_run else self._do_request
return func('patch', (url, payload), callback, kwargs)
对于assert_called_with
,参数和使用的关键字必须完全匹配。将参数替换为 ANY
将始终匹配参数值,但关键字仍必须与使用的关键字匹配。通用关键字 args
和 kwargs
也不例外:如果您需要它们,则必须在匹配调用中使用它们。
在这种情况下,预期调用中的 kwargs
关键字:
mock_patch.assert_called_with(url=ANY, payload=ANY, callback=ANY, async_run=ANY, kwargs=ANY)
必须改为真正使用的关键字svc_auth
:
mock_patch.assert_called_with(url=ANY, payload=ANY, callback=ANY, async_run=ANY, svc_auth=ANY)
请注意,这同样适用于关键字与位置参数,这是一个常见的陷阱。如果你有一个函数 foo(bar)
,那么你必须完全按照调用的方式进行调用,例如:
@mock.patch("my_module.foo")
def test_foo(patched):
foo(42)
patched.assert_called_with(ANY) # passes
patched.assert_called_with(foo=ANY) # fails
foo(bar=42)
patched.assert_called_with(ANY) # fails
patched.assert_called_with(foo=ANY) # passes
我目前正在尝试模拟对服务器的补丁请求,并且我正在尝试使用模拟对象库中的 ANY 属性。我有以下代码:
@patch('path_to_patch.patch')
def test_job_restarted_succesfully(mock_patch):
make_patch_call()
mock_patch.assert_called_with(url=ANY, payload=ANY, callback=ANY, async_run=ANY, kwargs=ANY)
我收到以下错误:
AssertionError: Expected call: patch(async_run=<ANY>, callback=<ANY>, kwargs=<ANY>, payload=<ANY>, url=<ANY>)
E Actual call: patch(async_run=True, callback=<function JobSvc.send_job_patch_request.<locals>.retry_on_404 at 0x000002752B873168>, payload={'analyzer': {'state': 'started'}, 'meta': {}}, svc_auth=UUID('40ed1a00-a51f-11eb-b1ed-b46bfc345269'), url='http://127.0.0.1:8080/rarecyte/1.0/jobs/slide1@20210422_203831_955885')
我在下面给出的文档中找到了 ANY,但无法弄清楚为什么 assert_called_once_with() 需要调用的实际参数。 这是文档中的相关部分:https://docs.python.org/3/library/unittest.mock.html#any
编辑: make_patch_call() 在计算出补丁函数所需的所有参数后最终调用此补丁函数。
def patch(self, url, payload, callback=None, async_run=False, **kwargs):
payload = self._serialize_payload(payload)
func = self._do_async_request if async_run else self._do_request
return func('patch', (url, payload), callback, kwargs)
对于assert_called_with
,参数和使用的关键字必须完全匹配。将参数替换为 ANY
将始终匹配参数值,但关键字仍必须与使用的关键字匹配。通用关键字 args
和 kwargs
也不例外:如果您需要它们,则必须在匹配调用中使用它们。
在这种情况下,预期调用中的 kwargs
关键字:
mock_patch.assert_called_with(url=ANY, payload=ANY, callback=ANY, async_run=ANY, kwargs=ANY)
必须改为真正使用的关键字svc_auth
:
mock_patch.assert_called_with(url=ANY, payload=ANY, callback=ANY, async_run=ANY, svc_auth=ANY)
请注意,这同样适用于关键字与位置参数,这是一个常见的陷阱。如果你有一个函数 foo(bar)
,那么你必须完全按照调用的方式进行调用,例如:
@mock.patch("my_module.foo")
def test_foo(patched):
foo(42)
patched.assert_called_with(ANY) # passes
patched.assert_called_with(foo=ANY) # fails
foo(bar=42)
patched.assert_called_with(ANY) # fails
patched.assert_called_with(foo=ANY) # passes