Karma测试没有加载AngularJS工厂

时间:2018-01-22 17:34:49

标签: javascript angularjs jasmine karma-runner karma-jasmine

我已将业力与现有项目整合在一起,我很难弄清楚为什么业力测试不会加载MathService工厂(math.js)。

文件夹结构

/tests
/www
+ /js
   + app.js
   + /controllers
   + /services
      + math.js
+ /lib

math.test.js

describe('MathService Spec', function() {

    var OfficerValidationService;

    beforeEach(function() {
      angular.module('starter');
    });

    beforeEach(inject(function() {
      var $injector = angular.injector(['starter']);
      OfficerValidationService = $injector.get('MathService');
    }));

    it('is very true', function(){
      //var output = OfficerValidationService.something();
      expect(OfficerValidationService).toBeTruthy();
    });

  });

app.js模块定义为

var app = angular.module('starter', ['ionic', 'ngCordova', 'pascalprecht.translate', 'textAngular', 'jett.ionic.content.banner', 'barcodeListener'])
  .constant('ENV', {
    mode: 'prod'
  })
  .run(function ($ionicPlatform, $rootScope, $translate,
    $timeout, $localstorage, $ionicHistory, $location, DatabaseService, ModeService, ArrowsysService) { /* code */ })

的MathService

app.factory('MathService', function () {
    return {
        roundNumber: function(toRound){
            if (toRound == 1) {
                return 1;
            } else {
                return 2;
            } 
        }
    },
    function roundNumber(toRound) {
        if (toRound == 1) {
            return 1;
        } else {
            return 2;
        }
    }
});

karma.conf.js

files: [
  'https://ajax.googleapis.com/ajax/libs/angularjs/1.6.7/angular.min.js',
  'https://cdnjs.cloudflare.com/ajax/libs/angular-mocks/1.6.8/angular-mocks.js',
  'www/js/app.js',
  'www/js/services/math.js',
  'tests/*.test.js'
],

结果表明MathService未定义。

Chrome 63.0.3239 (Windows 10 0.0.0) MathService Spec is very true FAILED
        Error: [$injector:modulerr] http://errors.angularjs.org/1.6.7/$injector/modulerr?p0=starter&p1=Error%3A%20%5B%24injector%3Amodulerr%5D%20http%3A%2F%2Ferrors.angularjs.org%2F1.6.7%2F%24injector%2Fmodulerr%3Fp0%3Dionic%26p1%3DError%253A%2520%255B%2524injector%253Anomod%255D%2520http%253A%252F%252Ferrors.angularjs.org%252F1.6.7%252F%2524injector%252Fnomod%253Fp0%253Dionic%250A%2520%2520%2520%2520at%2520https%253A%252F%252Fajax.googleapis.com%252Fajax%252Flibs%252Fangularjs%252F1.6.7%252Fangular.min.js%253A7%253A76%250A%2520%2520%2520%2520at%2520https%253A%252F%252Fajax.googleapis.com%252Fajax%252Flibs%252Fangularjs%252F1.6.7%252Fangular.min.js%253A26%253A408%250A%2520%2520%2520%2520at%2520b%2520(https%253A%252F%252Fajax.googleapis.com%252Fajax%252Flibs%252Fangularjs%252F1.6.7%252Fangular.min.js%253A25%253A439)%250A%2520%2520%2520%2520at%2520https%253A%252F%252Fajax.googleapis.com%252Fajax%252Flibs%252Fangularjs%252F1.6.7%252Fangular.min.js%253A26%253A182%250A%2520%2520%2520%2520at%2520https%253A%252F%252Fajax.googleapis.com%252Fajax%252Flibs%252Fangularjs%252F1.6.7%252Fangular.min.js%253A42%253A332%250A%2520%2520%2520%2520at%2520p%2520(https%253A%252F%252Fajax.googleapis.com%252Fajax%252Flibs%252Fangularjs%252F1.6.7%252Fangular.min.js%253A8%253A7)%250A%2520%2520%2520%2520at%2520g%2520(https%253A%252F%252Fajax.googleapis.com%252Fajax%252Flibs%252Fangularjs%252F1.6.7%252Fangular.min.js%253A42%253A180)%250A%2520%2520%2520%2520at%2520https%253A%252F%252Fajax.googleapis.com%252Fajax%252Flibs%252Fangularjs%252F1.6.7%252Fangular.min.js%253A42%253A364%250A%2520%2520%2520%2520at%2520p%2520(https%253A%252F%252Fajax.googleapis.com%252Fajax%252Flibs%252Fangularjs%252F1.6.7%252Fangular.min.js%253A8%253A7)%250A%2520%2520%2520%2520at%2520g%2520(https%253A%252F%252Fajax.googleapis.com%252Fajax%252Flibs%252Fangularjs%252F1.6.7%252Fangular.min.js%253A42%253A180)%0A%20%20%20%20at%20https%3A%2F%2Fajax.googleapis.com%2Fajax%2Flibs%2Fangularjs%2F1.6.7%2Fangular.min.js%3A7%3A76%0A%20%20%20%20at%20https%3A%2F%2Fajax.googleapis.com%2Fajax%2Flibs%2Fangularjs%2F1.6.7%2Fangular.min.js%3A43%3A99%0A%20%20%20%20at%20p%20(https%3A%2F%2Fajax.googleapis.com%2Fajax%2Flibs%2Fangularjs%2F1.6.7%2Fangular.min.js%3A8%3A7)%0A%20%20%20%20at%20g%20(https%3A%2F%2Fajax.googleapis.com%2Fajax%2Flibs%2Fangularjs%2F1.6.7%2Fangular.min.js%3A42%3A180)%0A%20%20%20%20at%20https%3A%2F%2Fajax.googleapis.com%2Fajax%2Flibs%2Fangularjs%2F1.6.7%2Fangular.min.js%3A42%3A364%0A%20%20%20%20at%20p%20(https%3A%2F%2Fajax.googleapis.com%2Fajax%2Flibs%2Fangularjs%2F1.6.7%2Fangular.min.js%3A8%3A7)%0A%20%20%20%20at%20g%20(https%3A%2F%2Fajax.googleapis.com%2Fajax%2Flibs%2Fangularjs%2F1.6.7%2Fangular.min.js%3A42%3A180)%0A%20%20%20%20at%20Object.hb%20%5Bas%20injector%5D%20(https%3A%2F%2Fajax.googleapis.com%2Fajax%2Flibs%2Fangularjs%2F1.6.7%2Fangular.min.js%3A46%3A250)%0A%20%20%20%20at%20UserContext.%3Canonymous%3E%20(http%3A%2F%2Flocalhost%3A9876%2Fbase%2Ftests%2Fmath.test.js%3Ff11444440ebffa5d88f933a1339ba01072b896ce%3A10%3A31)%0A%20%20%20%20at%20Object.invoke%20(https%3A%2F%2Fajax.googleapis.com%2Fajax%2Flibs%2Fangularjs%2F1.6.7%2Fangular.min.js%3A44%3A390)
            at https://ajax.googleapis.com/ajax/libs/angularjs/1.6.7/angular.min.js:7:76
            at https://ajax.googleapis.com/ajax/libs/angularjs/1.6.7/angular.min.js:43:99
            at p (https://ajax.googleapis.com/ajax/libs/angularjs/1.6.7/angular.min.js:8:7)
            at g (https://ajax.googleapis.com/ajax/libs/angularjs/1.6.7/angular.min.js:42:180)
            at Object.hb [as injector] (https://ajax.googleapis.com/ajax/libs/angularjs/1.6.7/angular.min.js:46:250)
            at UserContext.<anonymous> (tests/math.test.js:10:31)
            at Object.invoke (https://ajax.googleapis.com/ajax/libs/angularjs/1.6.7/angular.min.js:44:390)ngularjs/1.6.7/angular.min.js:44:390)                                libs/angular-mocks/1.6.8/angular-mocks.js:3183:20)            at UserContext.WorkFn (https://cdnjs.cloudflare.com/ajax/libs/angular-mocks/1.6.8/angular-mocks.js:3183:20)                   flare.com/ajax/libs/angular-mocks/1.6.8/angular-mocks.js:3146:25)        Error: Declaration Location            at window.inject.angular.mock.inject (https://cdnjs.cloudflare.com/ajax/libs/angular-mocks/1.6.8/angular-mocks.js:3146:25)
            at Suite.<anonymous> (tests/math.test.js:9:16)
            at tests/math.test.js:1:1                                 (0.009 secs / 0 secs)        
 Expected undefined to be truthy.            at UserContext.<anonymous> (tests/math.test.js:16:40)Chrome 63.0.3239 (Windows 10 0.0.0): Executed 1 of 1 (1 FAILED) ERROR (0.009 secs / 0 secs)Terminate batch job (Y/N)?

1 个答案:

答案 0 :(得分:1)

1)您应该使用angular-mocks而非module function提供的angular.module,因此所有测试都将在您的模块范围内运行,因此注入器将获得有关声明和依赖关系;

2)您可以将$injector服务作为inject() method回调中的一个参数或类似var $injector = angular.injector();的参数传递,但不是您的方式;

3)最好为你的MathService声明自己的module,因为要在starter模块的范围内运行测试,你必须提供/模拟所有依赖项,我不要我们认为您的MathService应该取决于ionicngCordova

请注意以上几点,这是一个如何在您的案例中测试服务的工作示例:

angular.module('starter', ['ionic', 'ngCordova', 'pascalprecht.translate', 'textAngular', 'jett.ionic.content.banner', 'barcodeListener', 'starter.services'])
    .constant('ENV', {
        mode: 'prod'
    })
    .run(function ($ionicPlatform, $rootScope, $translate,
                   $timeout, $localstorage, $ionicHistory, $location, DatabaseService, ModeService, ArrowsysService, MathService) {
        /* code */
    });

angular.module('starter.services', [])
    .factory('MathService', function () {

        function roundNumber(toRound) {
            if (toRound === 1) {
                return 1;
            } else {
                return 2;
            }
        }

        return {
            roundNumber: roundNumber
        }

    });

describe('MathService Spec', function () {

    var MathService;

    beforeEach(module('starter.services'));

    beforeEach(inject(function ($injector) {
        MathService = $injector.get('MathService');
    }));

    it('is very true', function () {
        expect(MathService).toBeTruthy();
    });

    it('roundNumber test', function () {
        expect(MathService.roundNumber(1)).toBe(1);
        expect(MathService.roundNumber(10)).toBe(2);
    });

});
.as-console-wrapper {
  height:0;
}
<!DOCTYPE html>
<html>

  <head>
    <!-- jasmine -->
    <script src="//cdnjs.cloudflare.com/ajax/libs/jasmine/2.8.0/jasmine.js"></script>
    <!-- jasmine's html reporting code and css -->
    <script src="//cdnjs.cloudflare.com/ajax/libs/jasmine/2.8.0/jasmine-html.js"></script>
    <link href="//cdnjs.cloudflare.com/ajax/libs/jasmine/2.8.0/jasmine.css" rel="stylesheet" />
    
    <script src="//cdnjs.cloudflare.com/ajax/libs/jasmine/2.8.0/boot.js"></script>
    <!-- angular itself -->
    <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.js"></script>
    <!-- angular's testing helpers -->
    <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular-mocks.js"></script>
  </head>

  <body>
    <!-- bootstrap jasmine! -->
  <script>
    var jasmineEnv = jasmine.getEnv();
    
    // Tell it to add an Html Reporter
    // this will add detailed HTML-formatted results
    // for each spec ran.
    jasmineEnv.addReporter(new jasmine.HtmlReporter());
    
    // Execute the tests!
    jasmineEnv.execute();
  </script>
  </body>

</html>

P.S。:如@Petr Averyanov所述,通过https://docs.angularjs.org/guide/unit-testing将是您更熟悉AngularJS单元测试的良好起点。