如何使用 John Papa 风格、Karma 和带有数据服务的 Jasmine 测试 angular 应用程序?

How to test angular app with John Papa style, Karma, and Jasmine with data service?

出于某种原因,即使按照 Josh 在 post 回复中提供的示例 How to test John papa vm.model unit testing with jasmine?, I can't get my controller's values to show up in the testing area. I think it's because of the data service, but it is a necessary component for our SPA, as is using 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§

我明白了。只需要看看 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),我需要一个奇怪的实现来使它全部工作。我现在在整个过程中都获得了成功的测试:

我希望这对遇到类似问题的其他人有所帮助。