如何通过模拟库模拟套接字对象 [英] How to mock a socket object via the mock library
问题描述
如何通过 mock 库(在Python 3中为unittest.mock
)?
How to mock a TCPSocket
wrapper for the socket
from the Python's standard libary via the mock library (unittest.mock
in case of Python 3)?
这是我的包装纸
import socket
import utils
class TCPSocket:
def __init__(self):
self.buf = ''
def __enter__(self):
pass
def __exit__(self, exc_type, exc_val, exc_tb):
self.close()
def connect(self, host, port):
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.sock.connect((host, port))
def close(self):
self.sock.close()
def send(self, data):
self.sock.send(data)
def sendall(self, data):
self.sock.sendall(data)
# For best match with hardware and network realities,
# the value of limit should be a relatively small power of 2, for example, 4096
def recv_some(self, limit=4096):
return self.sock.recv(limit)
def recv_bytes(self, count):
while len(self.buf) < count:
self.buf += self.recv_some()
parts = utils.split_first_n(self.buf, count)
self.buf = parts[1]
return parts[0]
def recv_until(self, delim):
while delim not in self.buf:
self.buf += self.recv_some()
parts = self.buf.split(delim, maxsplit=1)
self.buf = parts[1]
return parts[0]
我想测试一下recv_until和recv_bytes之类的函数是否满足其真正的需求.
I want to test whether functions like recv_until and recv_bytes do what they really need.
推荐答案
它可以很简单
import mock # or from unittest import mock
mock_socket = mock.Mock()
mock_socket.recv.return_value = data
然后在要使用实际套接字的地方使用mock_socket
.您还可以根据需要模拟任何创建套接字的东西,以返回一个模拟值,例如此处配置的值.
then use mock_socket
where you would use the real socket. You can also mock whatever creates the socket to return a mock value like the one configured here, depending on your needs.
对于您的情况,您可以模拟socket.socket
,以便它返回可以配置其方法的内容.请注意,本例中的mock_socket
是一个返回Socket
对象的函数,而不是返回Socket
对象本身的函数.
For your case, you can mock socket.socket
so that it returns something whose method you can configure. Note that mock_socket
in this example is a function that returns a Socket
object, not a Socket
object itself.
with mock.patch('socket.socket') as mock_socket:
mock_socket.return_value.recv.return_value = some_data
t = TCPSocket()
t.connect('example.com', 12345) # t.sock is a mock object, not a Socket
self.assertEqual(t.recv_bytes(), whatever_you_expect)
t.sock.connect.assert_called_with(('example.com', 12345))
这篇关于如何通过模拟库模拟套接字对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!