2

我有一个为角度控制器编写的 ES 类,我正在尝试使用 angular-mock 编写茉莉花测试。

在构造函数中,我将 $filter 初始化为 this.i18n = $filter('i18n),它基本上是一个本地化过滤器,它接受一个键、值并返回键的本地化值。

我的问题是,由于类的构造函数具有 $filter 并且稍后在类方法中使用。我的单元测试失败了。我如何使用 $filter 进行测试,以使我的测试不会失败。我正在寻找模拟自定义过滤器

这是我得到的例外

  TypeError: this.i18n is not a function
    at UsersCtrl.$onInit (test-context.js:35081:41)
    at Object.<anonymous> (test-context.js:35031:31)

这是 ES6 类

class UsersCtrl {
    constructor($filter) {
        this.i18n = $filter('i18n');
        this.users = [];
    }
   //Life cycle Hooks: Initialization
   $onInit() {
        this.users = [
            {name: this.i18n('USERS')}
        ];
      }
}
UsersCtrl.$inject = ['$filter'];

angular.module('app', []).controller('UsersCtrl',UsersCtrl);

export default UsersCtrl;

这是我拥有的单元测试

Import UsersCtrl from './users-controller.js';

     describe("given a new User Page", () => {
        var UserController;
        beforeEach(() => {
          angular.mock.module('app');
        });

    describe("when initialising  has completed", () => {
      beforeEach(() => {
         inject(($rootScope, $controller, $filter) => {
             const scope = $rootScope.$new();
             const filter = $filter
             UserController = $controller("UsersCtrl", { $scope: scope, $filter: filter});
          });
       });
    it("then users array for tab content should be empty initially",() => {
        const expectedActive = [];       
        expect(UserController.users).toEqual(expectedActive);
     });
    });
   });

问题是它运行测试但由于无法使用 this.i18n = $filter('i18n) 初始化而失败。我应该如何初始化测试以将 $filter 传递给测试?我可以模拟过滤器吗,因为我真的不想在这里测试过滤器

4

1 回答 1

1

您可以:

  • 当您在测试中实例化它时,模拟整个$filter服务并将其注入控制器;或者
  • 模拟单个过滤器。然后,您可以$provide.value(key, value)在加载模块时使用,其中键是过滤器名称加上后缀:' Filter '(这是 Angular 在注册过滤器时在内部执行的操作)。

两者的一个例子:

/* Angular App */
(function() {
  "use strict";

  class UsersCtrl {
    constructor($filter) {
      this.i18n = $filter('i18n');
      this.users = [];
    }

    $onInit() {
      this.users = [{
        name: this.i18n('USERS')
      }];
    }
  }

  UsersCtrl.$inject = ['$filter'];

  angular
    .module('app', [])
    .controller('UsersCtrl', UsersCtrl);

})();

/* Unit Test */
(function() {
  "use strict";

  describe('given a new User Page', () => {
    let UsersController;

    describe('MOCK entire $filter service: when initialising has completed', () => {
      beforeEach(() => {
        module('app');

        inject(($rootScope, $controller) => {
          UsersController = $controller("UsersCtrl", {
            $scope: $rootScope.$new(),
            $filter: () => {
              // $filter will be a function that returns a noop function (or whatever we want)
              return angular.noop;
            }
          });
        });
      });

      it('then users array for tab content should be empty initially', () => {
        const expectedActive = [];
        expect(UsersController.users).toEqual(expectedActive);
      });
    });

    describe('MOCK individual \'i18n\' filter: when initialising has completed', () => {
      beforeEach(() => {
        module('app', ($provide) => {
          // provide a mock (noop function) for our filter.
          // Note naming convention, our filter name + 'Filter' suffix.
          $provide.value('i18nFilter', angular.noop);
        });

        inject(($rootScope, $controller, $filter) => {
          UsersController = $controller("UsersCtrl", {
            $scope: $rootScope.$new(),
            $filter: $filter
          });
        });
      });

      it('then users array for tab content should be empty initially', () => {
        const expectedActive = [];
        expect(UsersController.users).toEqual(expectedActive);
      });
    });

  });

})();
<link rel="stylesheet" href="//cdn.jsdelivr.net/jasmine/2.0.0/jasmine.css" />
<script src="//cdn.jsdelivr.net/jasmine/2.0.0/jasmine.js"></script>
<script src="//cdn.jsdelivr.net/jasmine/2.0.0/jasmine-html.js"></script>
<script src="//cdn.jsdelivr.net/jasmine/2.0.0/boot.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular-mocks.js"></script>

于 2016-09-25T11:23:34.390 回答