【问题标题】:Why does my Jasmine spec think my Angular module is undefined为什么我的 Jasmine 规范认为我的 Angular 模块未定义
【发布时间】:2016-07-20 16:30:36
【问题描述】:

为什么我的 Jasmine 规范认为我的 Angular 模块未定义?我在实际模块代码下方添加了一行代码,将布尔值设置为 true,然后我从规范中对其进行 console.log,它表明为 true。我也尝试过更改模块,使其不是超范围(我的术语)或 IIFE,但这没有效果。错误信息的要点是Expected undefined to equal <jasmine.any(Object)>.

规范运行器:

<!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>

角度模块:

(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;

规格:

'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));
    })
});

【问题讨论】:

    标签: javascript angularjs unit-testing jasmine


    【解决方案1】:

    这个错误

    TypeError:无法读取未定义的属性“be”

    明确表示这段代码有问题

    expect(common).to.be.a('Object');
    

    而不是在common 服务中。

    这是因为代码是从使用 Chai 框架而不是 Jasmine 进行断言的规范中粘贴的,这两个具有不同的 API。 Chai 语法使用点分隔符,Jasmine 方法是驼峰式的。

    Jasmine 有简单的 API,被 on a single page 覆盖,规范应该变成

    expect(common).toEqual(jasmine.any(Object));
    

    common 变量可能静默变为undefined 的唯一情况是common 服务被意外覆盖以返回undefined。在任何其他情况下都会抛出注入错误。

    规范中的注入错误

    错误:[$injector:unpr] 未知提供程序:loggerProvider http://errors.angularjs.org/1.5.2/$injector/unpr?p0=loggerProvider%20%3C-%20logger%20%3C-%20common

    由于没有加载第三方模块文件,并且没有在common 模块中加载模块。

    解决此问题的一种方法是在规范中加载依赖项:

    beforeEach(module('loggerModuleName', 'toasterModuleName', 'common'));
    

    但最好的方法是修复common模块本身,因为模块应该明确声明其依赖关系,而不仅仅是依赖父模块来加载它们:

    var commonModule = angular.module('common', ['loggerModuleName', 'toasterModuleName']);
    

    【讨论】:

    • 好吧,我的错。但是common 仍然从第二个beforeEach 块中以未定义的形式出现。事实上,我什至不认为该块正在执行,我尝试将debugger 和/或console.log 放在该块中,并且语句不执行。第二个beforeEach 是否有效? jasmine API 对您来说可能很简单,但同样,这是我第一次接触它,我正在尝试将它与 Angular 集成以启动。任何进一步的方向表示赞赏。
    • 是的,第二个beforeEach 是正确的。如果服务注入出现问题,它不仅会静默失败,还会抛出特定错误,因此可以轻松追踪问题。如果没有错误,common 应该等于实际服务值。代码被截断,不显示 common factory 返回的内容。如果它没有返回任何东西,它将是undefined
    • 有一个return service 声明,我已经使用了两个月没有问题。在第二个beforeEach 之后,common 仍然是未定义的 :( 在您发送给我的那一行代码之后,我得到了一个不同的错误——请参阅上面的修改。
    • expect 仍然应该在 it 块内,就像在原始代码中一样。如果这是您之前尝试过的,这就是 beforeEach 块没有运行的原因 - 它在 每个 it 规范之前运行。如果没有就不会运行。我看不出为什么 common 可以在这里未定义的正当理由。如果您仍然遇到问题,我建议您在 Plunker 上复制该问题。还要注意 angular-mocks 应该在 Jasmine 和 Angular 之后加载。
    • 我想我有正确的加载各种文件的顺序。我将expect 放回it 中,现在出现此错误:“预期未定义等于。” common 来自第二个 beforeEach 未定义。我想我要修改我的问题以包括一个完整的服务,我去掉除了一种方法之外的所有内容。感谢您一直以来愿意提供帮助。
    猜你喜欢
    • 1970-01-01
    • 2012-02-22
    • 2018-10-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-27
    • 1970-01-01
    • 2015-02-10
    相关资源
    最近更新 更多