Why does my Jasmine spec think my Angular module is undefined

那年仲夏 提交于 2020-01-23 12:05:58

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!