Python pytest mock socket.recv问题

时间:2017-01-18 21:03:02

标签: python-2.7 mocking pytest

我在文件val extend = 1 val core = if (extend == 1) Module(new ExtendedCore(data_address)) else Module(new Core(data_address))

中有一个简单的Python类,如下所示(简化示例)
example.py

在另一个文件(import socket class MySocket(object): _connection = None def ConnectAndGetData(self, ip, port): self._connection = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self._connection.settimeout(10) self._connection.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1) self._connection.connect(ip, port) data = 0 return(data) )中,我进行了单元测试,如下所示:

test_example.py

这很好(from example import MySocket import mock class TestExample(object): @mock.patch('example.socket.socket.connect') def test_connect(self, mock_connect): IP = '10.10.10.10' port = '5000' my_socket = MySocket() data = my_socket.ConnectAndGetData(IP, port) mock_connect.assert_called_with(IP, port) 被嘲笑)。但是,现在我将connect方法添加到recv

example.py

以及import socket class MySocket(object): _connection = None def ConnectAndGetData(self, ip, port): self._connection = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self._connection.settimeout(10) self._connection.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1) self._connection.connect(ip, port) data = self._connection.recv(5) return(data)

的相应测试代码
test_example.py

现在这失败并显示以下消息......

from example import MySocket
import mock

class TestExample(object):

    @mock.patch('example.socket.socket.recv')
    @mock.patch('example.socket.socket.connect')
    def test_connect(self, mock_connect, mock_recv):
        IP = '10.10.10.10'
        port = '5000'
        mock_recv.side_effect = ["he", "llo"]
        my_socket = MySocket()
        data = my_socket.ConnectAndGetData(IP, port)
        mock_connect.assert_called_with(IP, port)
        assert data == "hello"

有人可以了解上面的错误(F self = <test_example.TestExample object at 0x032836F0> mock_connect = <MagicMock name='connect' id='52967856'> mock_recv = <MagicMock name='recv' id='45677456'> @mock.patch('example.socket.socket.recv') @mock.patch('example.socket.socket.connect') def test_connect(self, mock_connect, mock_recv): IP = '10.10.10.10' port = '5000' mock_recv.side_effect = ["he", "llo"] my_socket = MySocket() > data = my_socket.ConnectAndGetData(IP, port) examples\test_example.py:14: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ examples\example.py:9: in ConnectAndGetData self._connection = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # type: socket _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = <socket._socketobject object at 0x033EF6C0>, family = 2, type = 1 proto = 0, _sock = <socket object, fd=508, family=2, type=1, protocol=0> 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)) E AttributeError: '_socketobject' object attribute 'recv' is read-only ..\..\Python27Dev\lib\socket.py:194: AttributeError )吗?

感谢。

1 个答案:

答案 0 :(得分:0)

我在使用套接字测试时遇到过类似的问题,但是使用mockito进行了测试。我在下面包含了片段 - HTH:

>>> from mockito import when, unstub
>>> from mock import Mock
>>> import socket
>>> mock_socket = Mock(spec=socket.socket)
>>> attrs = { 'recv.return_value': u'this is the string returned' }
>>> mock_socket.configure_mock(**attrs)
>>> mock_socket.recv(1024)
u'this is the string returned'
>>> when(socket).socket(socket.AF_INET, socket.SOCK_STREAM).thenReturn(mock_socket)
<mockito.invocation.AnswerSelector object at 0x7fd102fd5890>
>>> from myapps.app1 import mysocket
>>> rc = mysocket.RestClient()
>>> rc.some_route()
"u'this is the string returned'"
>>> mock_socket.mock_calls
[call.recv(1024),
 call.connect(('daring.cwi.nl', 50007)),
 call.sendall('Hello, world'),
 call.recv(1024),
 call.close()]

和mysocket.py文件:

# Echo client program
import socket

HOST = 'daring.cwi.nl'    # The remote host
PORT = 50007              # The same port as used by the server

class RestClient():
    def some_route(self):
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.connect((HOST, PORT))
        s.sendall('Hello, world')
        data = s.recv(1024)
        s.close()
        return repr(data)