[英]Hard to understand return_value for Python Mock Class in the following example
I had a hard time understanding the choice of using return_value
.我很难理解使用
return_value
的选择。 See the following example看下面的例子
# my_module.py
def query(connection):
cursor = connection.cursor()
cursor.execute("SELECT name FROM users WHERE id = 1")
return cursor.fetchone()[0]
# test_query.py
import pytest
from unittest.mock import Mock
# Import the module containing the function to test
import my_module
def test_query():
# Set up the mock database connection
connection = Mock()
cursor = connection.cursor.return_value
cursor.fetchone.return_value = ("Alice",)
# Call the function under test
result = my_module.query(connection)
# Assert that the function has the expected behavior
assert result == "Alice"
My question is in test_query.py
, why do I need the first return_value
?我的问题在
test_query.py
中,为什么我需要第一个return_value
? It looks like if cursor = connection.cursor.return_value
, I can replace the cursor
in cursor.fetchone.return_value = ("Alice",)
, which then becomes connection.cursor.return_value.fetchone.return_value = ("Alice",)
?看起来如果
cursor = connection.cursor.return_value
,我可以替换cursor
中的cursor.fetchone.return_value = ("Alice",)
,然后变成connection.cursor.return_value.fetchone.return_value = ("Alice",)
? Why does this code require two return_value
?为什么这段代码需要两个
return_value
?
Without the first return_value
, I received TypeError: 'Mock' object is not subscriptable
after running pytest没有第一个
return_value
,我收到TypeError: 'Mock' object is not subscriptable
after running pytest
The broader question is when should I use return_value
?更广泛的问题是我什么时候应该使用
return_value
?
First lets make sure we understand what Mock is.首先让我们确保我们了解Mock是什么。 You can think of it as an object that's every attribute or function call returns another object of type Mock .
您可以将其视为每个属性的 object 或 function 调用返回另一个Mock类型的 object。
from unittest.mock import Mock
m = Mock()
for cls in [m, m.any_attribute, m.any_function("any_param"), m.any_function.return_value]:
assert isinstance(cls, Mock)
We can easilly implement such behaviour by ourself:我们可以很容易地自己实现这样的行为:
class MyMock:
def __getattribute__(self, _: str):
return MyMock()
def __call__(self, *args, **kwargs):
return MyMock()
However return_value
has a special meaning.然而
return_value
有特殊的含义。 With return value
you ask for (or set by yourself) result of calling specified function. return value
您要求(或自己设置)调用指定 function 的结果。
Now, what our goal is?现在,我们的目标是什么? Our goal is to make
cursor.fetchone()
function return something that is subscriptable (because we ask for first element with [0]
).我们的目标是使
cursor.fetchone()
function 返回可订阅的内容(因为我们要求第一个元素带有[0]
)。 But with such syntax:但是使用这样的语法:
connection.cursor.fetchone.return_value = ("Alice, )
We are mocking result of calling fetchone
from connection.cursor
, not connection.cursor()
.我们是 mocking 从
connection.cursor
调用fetchone
的结果,而不是connection.cursor()
。 It would work fine only if cursor
is a property
.只有当
cursor
是property
时,它才能正常工作。
To sum up, whenever you see a function call you use return_value
and in case of attributes you don't.总而言之,每当您看到 function 调用时,您都会使用
return_value
,如果是属性,则不会。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.