问题
Why does my Jasmine spec think my Angular module is undefined? I've added a line of code setting a boolean to true below the actual module code, and then I console.log it from within the spec, and it indicates true. I've also tried changing the module so it is not an ultra-scope (my term) or IIFE, but that has no effect. The gist of the error message is Expected undefined to equal <jasmine.any(Object)>.
Spec runner:
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Angular Spec Runner</title>
<link rel="shortcut icon" type="image/png" href="lib/jasmine-2.4.1/jasmine_favicon.png">
<link rel="stylesheet" type="text/css" href="lib/jasmine-2.4.1/jasmine.css">
<script type="text/javascript" src="lib/jasmine-2.4.1/jasmine.js"></script>
<script type="text/javascript" src="lib/jasmine-2.4.1/jasmine-html.js"></script>
<script type="text/javascript" src="lib/jasmine-2.4.1/boot.js"></script>
<script type="text/javascript" src="../../bower_components/angular/angular.min.js"></script>
<script type="text/javascript" src="https://code.angularjs.org/1.5.2/angular-mocks.js"></script>
<!-- include source files here... -->
<script type="text/javascript" src="../services/common/common.js"></script>
<!-- include spec files here... -->
<script type="text/javascript" src="specs/commonSpec.js"></script>
</head>
<body>
</body>
</html>
Angular module:
(function () {
'use strict';
var commonModule = angular.module('common', []);
commonModule.factory('common',
['$q', '$rootScope', '$timeout', '$location', 'logger', 'toaster', common]);
function common($q, $rootScope, $timeout, $location, logger, toaster) {
var throttles = {};
var service = {
isPhoneNumber: isPhoneNumber
};
return service;
function isPhoneNumber(phoneStr) {
phoneStr = phoneStr.replace(/\D/g, ''); //strips parens, dots, dashes, etc.
return phoneStr.length === 10
&& parseInt(phoneStr, 10) >= 2000000000 //area code can't start with 0 or 1
&& parseInt(phoneStr.slice(-7), 10) >= 2000000; //exchange can't start with 0 or 1
};
}
})();
window.commonModuleLoaded = true;
Spec:
'use strict';
describe('common', function () {
var common;
beforeEach(module('common'));
beforeEach(inject(function (_common_) {
common = _common_;
}));
console.log('window.commonModuleLoaded :' + window.commonModuleLoaded);
it('is an object', function () {
expect(common).toEqual(jasmine.any(Object));
})
});
回答1:
This error
TypeError: Cannot read property 'be' of undefined
clearly says that there's something wrong in this piece of code
expect(common).to.be.a('Object');
and not in common
service.
This results from the fact that the code was pasted from the spec that uses Chai framework for assertions and not Jasmine, those two have different APIs. Chai syntax uses dot separators, Jasmine methods are camel-cased.
Jasmine has simple API that is covered on a single page, the spec should become
expect(common).toEqual(jasmine.any(Object));
The only case when common
variable may become undefined
silently is when common
service was accidentally overridden to return undefined
. In any other case injection error would be thrown.
The injection error in the spec
Error: [$injector:unpr] Unknown provider: loggerProvider <- logger <- common http://errors.angularjs.org/1.5.2/$injector/unpr?p0=loggerProvider%20%3C-%20logger%20%3C-%20common
results from the fact that third-party module files weren't loaded and the modules weren't loaded in common
module.
A way to fix this is to load dependencies in spec:
beforeEach(module('loggerModuleName', 'toasterModuleName', 'common'));
But the preferable way is to fix common
module itself, because a module should explicitly state its dependencies, not just rely on parent module to load them:
var commonModule = angular.module('common', ['loggerModuleName', 'toasterModuleName']);
来源:https://stackoverflow.com/questions/38486014/why-does-my-jasmine-spec-think-my-angular-module-is-undefined