« Back to Index

Mocking a Window object for unit-testing purposes

View original Gist on GitHub

1. Example Spec.js

var mocks = {
    resizeCalled: false,

    createFakeWindow: function(width, height) {
        var module = this;

        return {
            document: {
                documentElement: {
                    clientWidth: width,
                    clientHeight: height
                }
            },

            history: {
                back: function(){}
            },

            location: {
                replace: function(){}
            },

            resizeTo: function(width, height) {
                this.document.documentElement = {
                    clientWidth: width,
                    clientHeight: height
                };
            }
        };
    },

    fireResizeEvent: function() {
        this.handler();
    },

    news: {
        $: function(element) {
            return {
                on: function(event, handler) {
                    if (event === 'resize') {
                        mocks.resizeCalled = true;
                    }
                    
                    mocks.handler = handler;
                }
            };
        }
    }
};

it('should bind to `resize` event on `init`', function(){
    var fakeWindow = mocks.createFakeWindow(320, 480);

    deviceInspector.init(fakeWindow, mocks.news);

    expect(mocks.resizeCalled).toBeTruthy();
});

it('should only publish `device` event when device type changes', function(){
    var fakeWindow = mocks.createFakeWindow(1008, 1024),
        device     = deviceInspector.init(fakeWindow, mocks.news);

    fakeWindow.resizeTo(960, 1024);
    mocks.fireResizeEvent();

    fakeWindow.resizeTo(320, 480);
    mocks.fireResizeEvent();
});

it('should take the user back to the previous page in their history', function(){
    var fakeWindow = mocks.createFakeWindow(),
        fakeWindowHistoryBackSpy = sinon.spy(fakeWindow.history, 'back'),
        fakeWindowLocationReplaceSpy = sinon.spy(fakeWindow.location, 'replace');

    pictureViewer.init(fakeWindow);

    $('.picture-viewer__button--back').trigger('click');

    expect(fakeWindowHistoryBackSpy).toHaveBeenCalledOnce();
    expect(fakeWindowLocationReplaceSpy).toHaveBeenCalledOnce();
});

2. Example Code.js

function bindEvents() {
    news.$(global).on('resize', handleResize);
}

function init(windowMock, newsMock) {
    global   = windowMock || window;
    news     = newsMock || newsModule;
}