python - Python module pytest-mock how to test method call arguments when one class call another class instance?
问题描述
I started out learning unit testing using pytest a couple of days ago, and got interested in the pytest-mock plugin (https://github.com/pytest-dev/pytest-mock).
I have been able to write quite a lot of unit tests to test my code, but now I would like to test how parts of my code interact with other objects. Let's say that I have class B, which is the class that I am interested in testing, that have a method that will call a method in class A, and I would like to assert that the method call was made with the expected arguments when class B make the call to class A.
I put together some example hack (see the link below) that will get the job done, but as you can see this is probably not the proper way of doing things. So my question is, how is this properly handled by using the Python mock or pytest-mock modules? Answers not based on the pytest-mock plugin are appreciated as well.
In the code below it is the assert that I am not happy about, since I would prefer to use the existing pytest-mock "assert_called_once_with(...)"-method, but I just can't get it to work. All information is available in the mock-object, but I don't understand how to properly use the pytest-mock API in this case.
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
参数,因为你在类中模拟了方法,所以它也接收self
.
要使用 assert_call_once_with 进行检查,您可以使用 mocker.ANY,它将接受任何内容:
mock_a.assert_called_once_with(mocker.ANY, nbr)
推荐阅读
- php - 只能循环一次 SQL 行?
- python - 为了解释两个论点的命题逻辑
- javascript - 通过 javascript 在 window.selection() 中查找 html 标签
- html - 无法让水平 scoll 菜单在 HTML 中工作
- ubuntu - 解密 GPG 文件
- php - Magento 网站迁移到 MAMP localhost。但是主页正在工作,但链接却没有。
- android - 我的应用程序布局在我运行时没有出现
- android - 带来工具的原因是什么:父布局中的上下文?
- npm - macOS High Sierra 的“zsh:找不到命令:create-react-app”
- php - 合并和求和具有相同 id 的项目