« Back to Index

Mocking the window object in JavaScript unit tests

View original Gist on GitHub

1. WindowMock.js

define([
    'module/bootstrap', // this is jQuery and PubSub libs
], function (lib) {
        var windowMock = {
            resizeSet: false, // set within the fake `lib` object below

            createFakeWindow: function(width, height) {
                return {
                    document: {
                        documentElement: {
                            clientWidth: width,
                            clientHeight: height
                        }
                    },

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

            fireResizeEvent: function() {
                this.handler(); // set within the fake `lib` object below
            },

            lib: {
                $: function(element) {
                    return {
                        on: function(event, handler) {
                            if (event === 'resize') {
                                windowMock.resizeSet = true;
                                windowMock.handler = handler;
                            }
                        }
                    };
                },

                pubsub: lib.pubsub
            }
        };

        return windowMock;
    }
);

2. Test Environment.js

function createFakeWindow (width, height) {
    var fakeWindow = WindowMock.createFakeWindow(width, height);

    someObject.init(fakeWindow, WindowMock.lib); // this can be removed or changed appropriately

    return fakeWindow;
}

function resizeWindow (width, height, fakeWindow) {
    document.body.style.width = width + 'px'; // remember to reset this in the test tear down
    fakeWindow.resizeTo(width, height);
    WindowMock.fireResizeEvent();
}

3. Code.js

define(['module/bootstrap'], function (lib) {
    var $, pubsub, someObject;

    someObject = {
        // Passing mocks to production code stinks!
        // Would love others to suggest a better solution
        init: function (windowMock, libMock) {
            this.global = windowMock || window;
            this.docEl = this.global.document.documentElement || document.documentElement;
            this.lib = libMock || lib;

            $ = this.lib.$;
            pubsub = this.lib.pubsub;
        }
    };

    return someObject;
});