diff --git a/src/ngMock/angular-mocks.js b/src/ngMock/angular-mocks.js index 54347abe3a45..fa06f86877ee 100644 --- a/src/ngMock/angular-mocks.js +++ b/src/ngMock/angular-mocks.js @@ -2480,6 +2480,15 @@ if (window.jasmine || window.mocha) { window.inject = angular.mock.inject = function() { var blockFns = Array.prototype.slice.call(arguments, 0); var errorForStack = new Error('Declaration Location'); + // some browsers, e.g. PhanthomJS, do not set a new error object's stack + // information until it has been thrown + if (!errorForStack.stack) { + try { + throw errorForStack; + } catch (e) { + errorForStack = e; + } + } return isSpecRunning() ? workFn.call(currentSpec) : workFn; ///////////////////// function workFn() { diff --git a/test/ngMock/angular-mocksSpec.js b/test/ngMock/angular-mocksSpec.js index 8a0cdd62e8a5..c1142a8c991c 100644 --- a/test/ngMock/angular-mocksSpec.js +++ b/test/ngMock/angular-mocksSpec.js @@ -919,6 +919,53 @@ describe('ngMock', function() { }); }).toThrow('test message'); })); + + describe('when called outside of test spec context and inject callback throws an Error', function() { + // - IE9 does not support providing stack traces + // - Chrome & Firefox give us the stack trace as soon as an Error is + // created + // - IE10, IE11 & PhantomJS give us the stack trace only once the error + // is thrown + var stackTraceSupported = (function() { + var error = new Error(); + if (error.stack) + return error.stack; + try { + throw error; + } catch (e) { + return e.stack; + } + })(); + + function testCaller() { + return inject(function() { + throw new Error(); + }); + } + var throwErrorFromInjectCallback = testCaller(); + + if (stackTraceSupported) { + describe('on browsers supporting stack traces', function() { + it('should update thrown Error stack with inject call location', function() { + try { + throwErrorFromInjectCallback(); + } catch (e) { + expect(e.stack).toMatch('testCaller'); + } + }); + }); + } else { + describe('on browsers not supporting stack traces', function() { + it('should not add stack trace information to thrown Error', function() { + try { + throwErrorFromInjectCallback(); + } catch (e) { + expect(e.stack).not.toBeDefined(); + } + }); + }); + } + }); }); });