Last Updated: February 25, 2016
·
5.141K
· wilk

AngularJS - ngWebsocket mock feature

Before reading this topic you may also want to read the previous one: HTML5 Websocket with AngularJS

This topic talks about ngWebsocket module

Developing with ngWebsocket

Working with HTML5 Websocket needs to have a listening backend that accepts a connection and responds with some data.
But what if we can develop and test our websocket application without a real backend?
I mean, with AngularJS you can use the $httpBackend service to mock an http webserver and this is actually useful for testing.
So, I think we can do it the same thing (no, wait, even better!) with ngWebsocket.

How? With an intriguing feature called mock.

Mock

Mock is a property that can be passed to the ngWebsocket constructor as follows:

angular.controller('MyCtrl', function ($websocket) {
    var ws = $websocket.$new({
        url: 'ws://localhost:12345',
        mock: true
    });
});

By default, mock is set to false.
However, if you pass a true boolean to it, it will be enabled and a websocket parrot server will be mocked.
This means that every event your ngWebsocket instance is going to emit will be intercepted by the internal
websocket server and get a response on the same event with the same data. Just like a parrot, right?

Let's see in action:

angular.controller('MyCtrl', function ($websocket) {
    var ws = $websocket.$new({
        url: 'ws://localhost:12345',
        mock: true
    });

    ws.$on('$open', function () {
        ws.$emit('a test', 'hello world');
        ws.$emit('another test', {
            my: 'awesome data'
        });
    });

    ws.$on('a test', function (message) {
        console.log(message); // 'hello world'
    });

    ws.$on('another test', function (message) {
        console.log(message.my); // 'awesome data'
    });
});

As you can see, this is really useful!
Why? Because you can develop your application without a real backend.

So, your backend team and you can setup a communication protocol (maybe in JSON) that let you to share data among
the frontend application and the backend.
In the meanwhile, the developing of your application can be done in parallel with the backend, even if they don't communicate at all.
When the backend is ready, just remove the mock property from the constructor and your application will send and
receive data to and from the server. If the protocol was followed correctly, you won't ever notice any change.

Testing

All what you said is great, really man, I'm serious!
But what about testing?

Well, dude, you got the point!
How can we make unit test to take advantage of the mock feature?

No sweat!
We're gonna take the above example and transform it in a useful unit test!

var $websocket;

describe('My awesome websocket unit test', function () {
    beforeEach(module('ngWebsocket')); // require the ngWebsocket module
    beforeEach(inject(function (_$websocket_) {
        $websocket = _$websocket_; // inject the $websocket service
    }));

    describe('Testing the websocket', function () {
        var ws;

        beforeEach(function (done) {
            ws = $websocket.$new({
                url: 'ws://localhost:12345',
                mock: true
            });

            ws.$on('$open', function () {
                done(); // enable all tests after the websocket connection is established
            });
        });

        it('should receive the same data on the same emitted event', function (done) {
            expect(ws.$status()).toEqual(ws.$OPEN);
            expect(ws.$ready()).toBeTruthy();

            ws.$emit('a test', 'hello world');
            ws.$emit('another test', {
                my: 'awesome data'
            });

            ws.$on('a test', function (message) {
                expect(message).toEqual('hello world');
            });

            ws.$on('another test', function (message) {
                expect(message.my).toEqual('awesome data');

                done(); // it works sequentially because the internal websocket server uses a queue to enqueues messages
            });
        });

        afterEach(function () {
            ws.$close(); // close the connection
        });
    });
});

Can you see the light? usually said a big man!

Yup! We do!
This is a real unit test example and it really works, even if there's no one line of backend code!

I'm going to show you how to use fixtures to mock a custom websocket server very soon, so stay tuned ;)

Have a fresh tip? Share with Coderwall community!

Post
Post a tip