0
votes

I have an application which dynamically updates the client side data whenever there comes data update on the server side. I am using AngularJS as front end and NodJS as the relay server. So when there is data update happens another application of someone else would post the data to my NodeJS server, which will be handled by a NodeJS route API (eg: route.post(/send)). For the testing purpose, I am using REST CLIENT for sending data to this API, and these all are working fine too.

When I do unit testing this route(/send) I should confirm whether there happens an event emit to the front end or not when I post a valid data to the node route right?. I am using mocha chai for unit test purpose. I could send the post request to the above-mentioned API using chai.request() method.But how can I verify whether API emitted the data to the client or not?.Below is my sample code and I think it is self-explanatory.

Issue facing is: This piece of code is working, and which is the proof of the success of the event being called.

 `server.on('gotData',function(){
     console.log('event emitted');
     assert(true);
     done();
   });`

Node Code:

router.post('/send', jsonParser, function (req, res) {
      //some logic here
      io.to(socketId).emit('gotData', data);
});

Client side

var socket = io.connect(serverUrl);
socket.on('gotData', function(data){
      console.log('Data got in client side');                         
});

Test Suite:

it('should be sent event to client-side when valid object has provided', function (done) {
   chai.request(server)
                .post('/send')
                .set({'Content-Type':'application/json'})
                .send(data);

   var socket;
   socket = io.connect(server);
   socket.on('gotData',function(){
     console.log('event emitted'); // not get firing after chai request
     assert(true);
     done();
   });
});
1

1 Answers

0
votes

I'm not really sure what you are asking, but your tests can become more focused if they ignore the event plumbing and router plumbing and focus on the logic of your test. If you audit your router, and io framework and both have tests to reasonably verify that event emissions work then you could isolate your specific logic and only exercise it:

router.post('/send', jsonParser, function (req, res) {
      //some logic here
      io.to(socketId).emit('gotData', data);
});

could become:

function yourSendHandler(req, res, ioModule) {
   // allow for user passed in ioModule, if not present use global
   var io = ioModule || io;
   //some logic here
   io.to(socketId).emit('gotData', data);
}
router.post('/send', jsonParser, yourSendHandler);

Now, if you export your handler, your test can import and exercise yourSendHandler directly, without having to worry about events, you could provide a mock io in your unit test and assert on its calls.

Having your function defined anonymously in the router couples it tightly to the router and doesn't allow for easy isolation or testing.