Tornado unit test with web sockets - what about stack context?

I have been using a tornado server for a while, and I have to say that I like it. I have a tornado server (which runs on python3.2) that handles web sockets and HTTP requests. I want to write some unit tests (which use web sockets) using ws2py (which implements a ws client for use with the IOLoop tornado). I see that the tornado has an AsyncTestCase class that looks pretty interesting, especially when used with AsyncHTTPClient, as stated in the doc :

class MyTestCase2(AsyncTestCase): def test_http_fetch(self): client = AsyncHTTPClient(self.io_loop) client.fetch("http://www.tornadoweb.org/", self.stop) response = self.wait() # Test contents of response self.assertIn("FriendFeed", response.body) 

I would like to use AsyncTestCase with web sockets, the Client is not a problem, I can send and receive messages without problems.

I assume that I need to pass self.stop client as a callback in order to receive the received message by calling wait() , as in the above example. But for some reason this will not work, here is what I have:

 class SQLRequests(AsyncTestCase): """Tests sql requests""" def test_sql_req_1(self): """first test function""" client = AsyncWSClient(httpBaseUrl, self.io_loop) client.sendMessage('some_message', self.stop) response = self.wait() if response.data: print('got %s' % str(response.data)) # some test self.assertTrue(True) if __name__ == '__main__': unittest.main() 

This is my web socket client:

 class AsyncWSClient(TornadoWebSocketClient): """ Asynchronous web socket client based on ws4py tornadoclient Sends a message and calls callback with received message """ def __init__(self, url, ioLoop=None, **kwargs): TornadoWebSocketClient.__init__(self, url, io_loop=ioLoop, **kwargs) self._callback = None self._message = None def opened(self): """called when web socket opened""" self.send(self._message, binary=False) def received_message(self, message): """Received a message""" self.close() if self._callback: self._callback(message) def sendMessage(self, message, callback): """Connects and sends message when connected""" self._message = message self._callback = callback self.connect() 

I get the ws2py.messaging.TextMessage object as an answer, but its data field is None , although some data was received by the client. If I look at AsyncTestCase before it calls the callback, this object has some data in it that disappears somewhere when it is passed as the return value of wait ().

I see that there is a mysterious thing in the tornado called stack_context, is something related to my problem?

+3
source share
1 answer

The problem is that the "data" message is contained in the data message attribute. When received_message is called, message.data reset to None ( https://github.com/Lawouach/WebSocket-for-Python/blob/master/ws4py/websocket.py#L369 ).

So, just call your message.data callback, not the full message . For example:

 def received_message(self, message): """Received a message""" self.close() if self._callback: self._callback(message.data) 
+4
source

All Articles