4

I am fairly new to javascript and am trying to use jasmine to unit test some error-handling code.

In particular, I'm trying to write some tests that verify that our custom code (called windowHandleError) that replaces window.onerror() gets called, and is doing what we want it to.

I've tried something along the lines of:

       it("testing window.onerror", function() {
        spyOn(globalerror, 'windowHandleError');
        globalerror.install();

        var someFunction = function() {
            undefinedFunction();
        };
        expect(function() {someFunction();}).toThrow();
        expect(globalerror.windowHandleError).toHaveBeenCalled();
    });

But it doesn't trigger the onerror. There are some related questions I've looked at, but they seem to ask about specific browsers, or how/where to use onerror instead of how to test it.
window.onerror not firing in Firefox
Capturing JavaScript error in Selenium
window.onerror does not work
How to trigger script.onerror in Internet Explorer?

Based on what some of those said, I thought running the spec tests in a debugger would force the onerror to trigger, but no dice. Anyone know a better approach to this?

Community
  • 1
  • 1
Metz
  • 43
  • 1
  • 6

2 Answers2

3

I recently developed small JavaScript error handler with unit tests based on Buster.JS which is similar to Jasmine.

The test that exercises the window.onerror looks like this:

  "error within the system": function (done) {

    setTimeout(function() {
      // throw some real-life exception
      not_defined.not_defined();
    }, 10);

    setTimeout(function() {
      assert.isTrue($.post.called);
      done();
    }, 100);
  }

It throws a real-life error within a setTimeout callback which will not stop the test execution and will check that a spy was called after 100ms in another setTimeout and then call done() which is how you test async functionality with Buster.JS. The same approach is available with Jasmine by using done() in async tests.

Lachezar
  • 6,523
  • 3
  • 33
  • 34
1

Without knowledge of Jasmine.

All unit tests run inside a try/catch block so that if one test dies, the next test can run (True for QUnit at least). And since window.onerror doesn't catch exceptions that is already caught inside a try/catch, it will not run when testing this in a unittest.

Try calling the onerror function manually based on the exception.

try {
    //Code that should fail here.
    someUndefinedFunction();
} catch (e) {
    window.onerror.call(window, e.toString(), document.location.toString(), 2);
}

expect(globalerror.windowHandleError).toHaveBeenCalled();

This is far from perfect as document.location is not the same as the url argument, and you need to manually set line number. A better way would be to parse e.stack for the correct file and line number.

When calling the function like this inside a unit test, it might be a better idea to simply test that your function is set and that it functions properly when called with all faked arguments.

AndersE
  • 332
  • 1
  • 4
  • 9