Python 模块 pytest-mock 如何在一个 class 调用另一个 class 实例时测试方法调用参数?
Python module pytest-mock how to test method call arguments when one class call another class instance?
我几天前开始使用 pytest 学习单元测试,并对 pytest-mock 插件 (https://github.com/pytest-dev/pytest-mock) 产生了兴趣。
我已经能够编写很多单元测试来测试我的代码,但现在我想测试我的部分代码如何与其他对象交互。假设我有 class B,这是我有兴趣测试的 class,它有一个方法可以调用 class A 中的方法,我想断言当 class B 调用 class A.
时,方法调用是使用预期参数进行的
我整理了一些示例 hack(请参阅下面的 link)来完成工作,但如您所见,这可能不是正确的做事方式。所以我的问题是,如何使用 Python mock 或 pytest-mock 模块正确处理这个问题?也感谢不基于 pytest-mock 插件的答案。
在下面的代码中,这是我不满意的断言,因为我更愿意使用现有的 pytest-mock "assert_called_once_with(...)"-方法,但我就是无法让它工作。所有信息都在模拟对象中可用,但我不明白如何在这种情况下正确使用 pytest-mock API。
def test_how_class_b_interact_with_class_a(mocker):
class A(object):
def further_process_nbr(self, nbr):
pass # don't care for the sake of this example
class B(object):
def __init__(self):
self.a = A()
def process_nbr(self, nbr):
nbr += 2 # do something fancy with number and then have it further processed by object a
return self.a.further_process_nbr(nbr)
nbr = 4
expected = 6
# Prepare
mock_a = mocker.patch.object(A, 'further_process_nbr', autospec=True)
# Exercise
B().process_nbr(nbr)
# Assert
assert mock_a.call_args_list[0].args[1] == expected # This is working, but not exactly a nice way
# mock_a.assert_called_once_with(expected) something like this is basically what I would like to do
实际上您看到的结果是正确的,在:
assert (<a.A object at 0x000001628C6878B0>, 2) == (2,)
你在元组的第一个元素中看到的是self
参数,因为你mock了class中的方法,所以它也接收self
。
要检查 assert_called_once_with,您可以使用 mocker.ANY,它将接受任何内容:
mock_a.assert_called_once_with(mocker.ANY, nbr)
我几天前开始使用 pytest 学习单元测试,并对 pytest-mock 插件 (https://github.com/pytest-dev/pytest-mock) 产生了兴趣。
我已经能够编写很多单元测试来测试我的代码,但现在我想测试我的部分代码如何与其他对象交互。假设我有 class B,这是我有兴趣测试的 class,它有一个方法可以调用 class A 中的方法,我想断言当 class B 调用 class A.
时,方法调用是使用预期参数进行的我整理了一些示例 hack(请参阅下面的 link)来完成工作,但如您所见,这可能不是正确的做事方式。所以我的问题是,如何使用 Python mock 或 pytest-mock 模块正确处理这个问题?也感谢不基于 pytest-mock 插件的答案。
在下面的代码中,这是我不满意的断言,因为我更愿意使用现有的 pytest-mock "assert_called_once_with(...)"-方法,但我就是无法让它工作。所有信息都在模拟对象中可用,但我不明白如何在这种情况下正确使用 pytest-mock API。
def test_how_class_b_interact_with_class_a(mocker):
class A(object):
def further_process_nbr(self, nbr):
pass # don't care for the sake of this example
class B(object):
def __init__(self):
self.a = A()
def process_nbr(self, nbr):
nbr += 2 # do something fancy with number and then have it further processed by object a
return self.a.further_process_nbr(nbr)
nbr = 4
expected = 6
# Prepare
mock_a = mocker.patch.object(A, 'further_process_nbr', autospec=True)
# Exercise
B().process_nbr(nbr)
# Assert
assert mock_a.call_args_list[0].args[1] == expected # This is working, but not exactly a nice way
# mock_a.assert_called_once_with(expected) something like this is basically what I would like to do
实际上您看到的结果是正确的,在:
assert (<a.A object at 0x000001628C6878B0>, 2) == (2,)
你在元组的第一个元素中看到的是self
参数,因为你mock了class中的方法,所以它也接收self
。
要检查 assert_called_once_with,您可以使用 mocker.ANY,它将接受任何内容:
mock_a.assert_called_once_with(mocker.ANY, nbr)