jcollum
jcollum

Reputation: 46599

how should I test client/server socket.io in mocha?

How does one properly shutdown socket.io / websocket-client? -- related, but out of date / didn't work

I'm writing a set of tests to test a server-side socket. Got the code from jamescarr on github. Carr's code is based on Liam Kaufman's here. Wall of text incoming.

This is the test side.

ioServer = require("socket.io")
ioClient = require("socket.io-client")

chai.should()
chai.use(sinonChai)
expect = chai.expect

server = require('./testUtils/chat-server.coffee')

socketURL = 'http://localhost:5000'

options =
  transports: ['websockets']
  'force new connection':true

chatUser1 = name:'Tom'
chatUser2 = name:'Sally'
chatUser3 = name:'Dana'

describe "Chat Server", ->
  before (done) ->
    server.start 5000, done
  after (done) ->
    server.stop done

  it "Should broadcast new user to all users", (done) ->
    console.log "new user to all users"
    client1 = ioClient.connect(socketURL)
    client1.on "connect", (data) ->
      client1.emit "connection name", chatUser1
      client2 = ioClient.connect(socketURL, options)
      client2.on "connect", (data) ->
        client2.emit "connection name", chatUser2

      client2.on "new user", (usersName) ->
        usersName.should.equal chatUser2.name + " has joined."
        client2.disconnect()

    numUsers = 0
    client1.on "new user", (usersName) ->
      numUsers += 1
      if numUsers is 2
        usersName.should.equal chatUser2.name + " has joined."
        client1.disconnect()
        done()

and this is the server side.

io = null
clients = {}

module.exports = 
  start: (port, cb) ->
    io = require("socket.io").listen port, cb
    io.sockets.on "connection", (socket) ->
      console.log "server on connection"
      userName = ''
      socket.on "connection name", (user) ->
        console.log "server on connection name"
        clients[user.name] = socket
        userName = user.name
        io.sockets.emit "new user", user.name + " has joined."

      socket.on 'message', (msg) ->
        console.log "server on message"
        io.sockets.emit 'message', msg

      socket.on 'private message', (msg) ->
        console.log "server on private message"
        fromMsg =
          from: userName
          txt: msg.txt
        clients[msg.to].emit 'private message', fromMsg
  stop: (cb) ->
    io.server.close()
    cb()

For some reason, no matter what I do, I get a timeout on the connection:

......   info  - socket.io started                                                                                           
new user to all users                                                                                                        
.15:55:06                                                                                                                    
.......................                                                                                                      

  × 1 of 45 tests failed:                                                                                                    

  1) Chat Server Should broadcast new user to all users:                                                                     
     Error: timeout of 2000ms exceeded                                                                                       
      at Object.<anonymous> (c:\Users\jcollum\AppData\Roaming\npm\node_modules\mocha\lib\runnable.js:167:14)                 
      at Timer.list.ontimeout (timers.js:101:19)                                                                             


  - watching   debug - emitting heartbeat for client 9VqXYQIv39VLoLVZB-Gw                                                    
   debug - websocket writing 2::                                                                                             
   debug - set heartbeat timeout for client 9VqXYQIv39VLoLVZB-Gw                                                             
  \ watching   

Upvotes: 2

Views: 3148

Answers (1)

jcollum
jcollum

Reputation: 46599

Five days, no answers so:

Here's what I've learned.

  1. Any test with a (done) in the signature will have to call done or it will fail (duh).
  2. Set up your callbacks, put the done call into the last one.
  3. If there are two connections and they interact, put the behavior of the second connection in the connect callback of the first.
  4. Finally, kick off the "seed" connection at the end of the test.

Upvotes: 5

Related Questions