如何使用John Papa风格,Karma和Jasmine测试角度应用程序并提供数据服务?

时间:2015-08-11 17:05:58

标签: javascript angularjs unit-testing karma-jasmine

出于某种原因,即使按照Josh在回复How to test John papa vm.model unit testing with jasmine?中提供的示例,我也无法将控制器的值显示在测试区域中。我认为这是因为数据服务,但它是我们SPA的必要组件,就像使用John Papa's styling一样。

下面是一个代码片段,用于保存代码并显示我收到的错误。

(function() {
  'use strict';
  angular.module('tickets')
    .service("DataService", DataService)

  /* @ngInject */
  DataService.$inject = ["$rootScope", "$q"];

  function DataService($rootScope, $q) {
    var vm = this;
    vm.nameDefault = "Name -- Please Authenticate";
    vm.name = vm.nameDefault;
  };

})();

(function() {
  'use strict';
  angular.module('tickets')
    .controller('HomeController', HomeController);

  /* @ngInject */
  HomeController.$inject = ['$scope', '$location', 'DataService'];

  function HomeController($scope, $location, DataService) {
    var vm = this;
    vm.name = DataService.name;
    vm.nameDefault = DataService.nameDefault;
  };

})();
<link href="https://cdnjs.cloudflare.com/ajax/libs/jasmine/2.1.0/jasmine.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/jasmine/2.1.0/jasmine.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jasmine/2.1.0/jasmine-html.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jasmine/2.1.0/boot.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.0-beta.4/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.0-beta.4/angular-mocks.js"></script>

<script>
  'use strict';

  describe('Controller: HomeController', function() {

    beforeEach(module('tickets'));

    var controller, $location, DataService;
    var tests = 0;

    beforeEach(inject(function($controller, _$location_, _DataService_) {
      $location = _$location_;
      DataService = _DataService_;
      scope = {};

      controller = $controller('HomeController', {});
    }));

    var controller, scope, $location, DataService;
    var tests = 0;

    /* // This version works up until I try to verify the name and nameDefault in controller \\
     *
     *    beforeEach(inject(function ($rootScope, $controller, _$location_, _DataService_) {
     *        $location = _$location_;
     *        DataService = _DataService_;
     *        scope = $rootScope.$new();
     *
     *        controller = function () {
     *            return $controller('HomeController', {});
     *        };
     *    }));
     */

    afterEach(function() {
      tests += 1;
    });

    describe('local variables', function() {

      describe('load the data model and values for all pertinent variables', function() {
        it('should be instantiated', function() {
          expect(DataService).toBeDefined();
        });
        it('should contain a name with an initial value before authentication', function() {
          expect(DataService.nameDefault).toBe('Name -- Please Authenticate');
          expect(DataService.name).toEqual(DataService.nameDefault);
        });
      });
      describe('should load the controller with data model values, and update as data model values update', function() {
        it('should be instantiated', function() {
          expect(controller).toBeDefined();
        })
        it('should not have a vm attribute that can be reached from here', function() {
          expect(controller.vm).toBeUndefined();
        })
        it('should contain a name with an initial value before authentication, both from the data model', function() {
          expect(controller.name).toBe(DataService.name);
          expect(controller.nameDefault).toBe(DataService.nameDefault);
        });
      });
    });

    it('should have tests', function() {
      expect(tests).toBeGreaterThan(0);
    });
  });
</script>

我的代码,当我在我们的本机环境中使用它时,用于验证数据服务中的所有内容是否已正确实例化(并使用注释掉的beforeEach块),但使用上面引用的问题中的示例的样式抛出关于范围未被实例化的更多错误,即使它与该问题相同(添加了依赖关系)。

我希望答案类似于(目前尚未回答的)问题:How to test John papa vm.model controllers and factories unit testing with jasmine?

我感谢你们提供的任何帮助。

-C§

编辑尽管我已经回答并取得了成功,但我希望得到一些反馈,说明为什么下面的实施有效,而其他两次尝试却没有。这是使用Karma版本0.13.8(最新),jasmine 2.1.0和Angular 1.4.0。

我知道我似乎很快就想出了解决方案,但是自从星期五下午(8/7)以来我一直在努力解决这个问题,尝试了十几种不同的格式但没有成功。

再次,我欢迎您的评论和投票,以便我能更好地理解为什么下面的版本有效,而其他版本没有,特别是因为我对AngularJS仍然非常环保(现在是1个月)。

再次感谢,

-C§

1 个答案:

答案 0 :(得分:2)

我现在明白了。只需看看Globally mock object in angularjs for jasmine/karma testing,我的大脑就会点击。

测试开始时的声明和beforeEach块需要如下所示:

    var controller, scope, $location, DataService;
    var tests = 0;

    beforeEach(inject(function ($rootScope, $controller, _$location_, _DataService_) {
    $location = _$location_;
    DataService = _DataService_;
    scope = $rootScope.$new();

    controller = $controller('HomeController', {
            $scope: scope
        });
    }));

我认为既然我已经把我们的初始设置搞得太多了(从模板启动SPA),我需要一个奇怪的实现来使它全部工作。我现在正在进行成功的测试:

enter image description here

我希望这可以帮助其他有类似问题的人。