[编辑:这个问题只存在于 Python 2.7。使用 3.7 它可以按预期工作。任何想法可能有什么区别,以及是否有可能使它也适用于 2.7,由于某些原因我必须使用它]
我想sendto
使用 Mock 覆盖套接字的方法。我的第一种方法是这样的:
class TestClass01(TestCase):
@mock.patch.object(socket.socket, "sendto", new=mock_sendto)
def test_function1(self):
...
但是,这导致了异常:
AttributeError:“_socketobject”对象属性“sendto”是只读的。
这种方法适用于其他类,但不适用于套接字。我接受它,原因是__init__
为所有成员函数调用 setattr,如下所示:
def __init__(self, family=AF_INET, type=SOCK_STREAM, proto=0, _sock=None):
if _sock is None:
_sock = _realsocket(family, type, proto)
self._sock = _sock
for method in _delegate_methods:
setattr(self, method, getattr(_sock, method)) <<<<<<<<<<<<<
然后,我尝试了另一种方法:
class TestClass01(TestCase):
@mock.patch("socket.socket")
def test_function1(self, mock_class):
s = mock.Mock(socket.socket)
s.sendto = mock_sendto
s.close = mock_close
mock_class.return_value = s
# ... run my tests here ...
args, kwargs = mock_class.call_args_list[0]
# Check arguments passed to sendto
这行得通,但是,调用参数列表只给了我:
((2, 2), {})
对应于构造函数AF_INET=2
和SOCK_DGRAM=2
。没有我调用的痕迹sendto
。我的解决方法是使用从mock_sendto
函数中设置的全局变量。不过,不是很优雅。
我有三个问题:
- 我可以解决“只读”问题并获得最初的工作方法吗?
- 为什么
all_args_list
只跟踪构造的调用而不跟踪 sendto 的调用? - 有比使用全局变量更好的方法吗?
提前感谢您的回答!