Mocking XHR

Answer to SO question

HTML

<script src="http://pivotal.github.io/jasmine/lib/jasmine-1.3.1/jasmine.js"></script>
<script src="http://pivotal.github.io/jasmine/lib/jasmine-1.3.1/jasmine-html.js"></script>
<link rel="stylesheet" href="http://pivotal.github.io/jasmine/lib/jasmine-1.3.1/jasmine.css">
<script src="http://code.angularjs.org/1.2.0/angular.js"></script>
<script src="http://code.angularjs.org/1.2.0/angular-mocks.js"></script>
<script src="http://code.angularjs.org/1.2.0/angular-cookies.js"></script>

JavaScript

//--- CODE --------------------------
var app = angular.module('app', []);
app.controller('MyCtrl', ['$scope', function ($scope) {
    var FormData = function () {
        this.append = function () {};
    };
    $scope.files = [];
    $scope.uploadFile = function () {
        var fd = new FormData();
        for (var i in $scope.files) {
            fd.append("uploadedFile", $scope.files[i]);
        }
        var xhr = new XMLHttpRequest();
        xhr.addEventListener("load", $scope.uploadComplete, false);
        xhr.addEventListener("error", $scope.uploadFailed, false);
        xhr.open("POST", "/fileupload");
        xhr.send(fd);
    };
}]);

// --- SPECS -------------------------

describe('app', function () {

    var controller,scope;
    beforeEach(function () {
        module('app');
        inject(function ($rootScope, $controller) {
            scope = $rootScope.$new();
            controller = $controller('MyCtrl', {
                $scope: scope
            });
        });
    });

    it("using $window ", function () {
        xhrObj = jasmine.createSpyObj('xhrObj', 
                                      ['addEventListener', 'open', 'send']);
        spyOn(window, "XMLHttpRequest").andReturn(xhrObj);

        scope.uploadFile()

        expect(xhrObj.addEventListener).toHaveBeenCalled();
        expect(xhrObj.addEventListener.calls.length).toBe(2);
    });
});

// --- Runner -------------------------
(function () {
    var jasmineEnv = jasmine.getEnv();
    jasmineEnv.updateInterval = 1000;

    var htmlReporter = new jasmine.HtmlReporter();

    jasmineEnv.addReporter(htmlReporter);

    jasmineEnv.specFilter = function (spec) {
        return htmlReporter.specFilter(spec);
    };

    var currentWindowOnload = window.onload;

    window.onload = function () {
        if (currentWindowOnload) {
            currentWindowOnload();
        }
        execJasmine();
    };

    function execJasmine() {
        jasmineEnv.execute();
    }

})();