【问题标题】:How to unit test a filter in AngularJS 1.x如何在 AngularJS 1.x 中对过滤器进行单元测试
【发布时间】:2014-02-01 09:25:10
【问题描述】:

如何在 Angular 中对过滤器进行单元测试?

【问题讨论】:

标签: javascript angularjs jasmine angularjs-filter


【解决方案1】:

注入$filter,然后用$filter('filterName')(input, options);调用它

所以要测试这个模板的等价物{{ foo | testFilter:capitalize }}

describe('The test filter', function () {
  'use strict'; 

  var $filter;

  beforeEach(function () {
    module('myTestFilterModule');

    inject(function (_$filter_) {
      $filter = _$filter_;
    });
  });

  it('should capitalize a string', function () {
    // Arrange.
    var foo = 'hello world', result;

    // Act.
    result = $filter('testFilter')(foo, 'capitalize');

    // Assert.
    expect(result).toEqual('HELLO WORLD');
  });
});

【讨论】:

  • 如果您使用 mocha/chai,您只需将期望更改为:expect(result).to.equal('HELLO WORLD');
  • 我不知道我是否在 foo 之后跟随 'capitalize'。有人可以向我解释一下目的吗?
  • 我添加了示例模板语法,以便您了解它的来源。它最终只是一个过滤器参数,一些过滤器没有这些参数,但使答案更完整 IMO
  • 这适用于我的 chrome 但不适用于 firefox 或 phantomjs。
【解决方案2】:

您可以注入 $filter 并加载要测试的过滤器。然后你通过你注入的过滤器传递要过滤的参数,你“期望”你需要什么。 这是一个例子:

describe('Filter test', function(){

  var filter;

  beforeEach(function(){
    module.apply(moduleName);

    inject(function($injector){
      filter = $injector.get('$filter')('nameOfTheFilter');
    });
  });

  it('should filter the parameters passed', function(){
    expect(filter(parameterToBeFiltered)).toBe(Result);
  });
});

【讨论】:

    【解决方案3】:

    过滤器可以直接注入测试(找到了一个sn-p here

      describe('myApp', function () {
    
        beforeEach(function () {
          module('myApp');
        });
    
        it('has a bool filter', inject(function($filter) {
          expect($filter('bool')).not.toBeNull();
        }));
    
        it("should return true empty array ", inject(function (boolFilter) {
          expect(boolFilter(true)).toBeTruthy();
        }));
    
      });
    

    在此示例中,过滤器名称为 'bool',为了注入此过滤器,您应使用 'bool' + 'Filter' = 'boolFilter'

    【讨论】:

    • 你不应该依赖实际代码,模拟出来 ````` module('myApp'); ````` 你正在调用整个应用程序,这意味着运行实际代码。
    【解决方案4】:

    除了注入实际的$filterservice 之外,还有其他方法可以测试过滤器。

    例子:

    describe('FILTER: myFilterName', function(){ // You can put anything in the string here,
                                                 // I like declaring FILTER: myFilterName, but it 
                                                 // could be just the filter name.
    
    var myTestTheFilterVariableName;
    // This variable does not have to match the describe name, call it what you wish,
    // but use this variable in any it blocks below.
    
    beforeEach(module('obsidian')); // Include app - boilerplate.
    
    beforeEach(inject(function(actualFilterNameFilter){
    // If your test variable name is the same as 'actualFilterNameFilter' then you would 
    // use this name '_actualFilterNameFilter_' with underscores; The Angularjs injector will
    // remove the underscores for you.
    // IMPORTANT PART: The important part here is the trailing 'Filter' name. This is how Angularjs
    // Knows to grab the filter title "actualFilterName" in this case.
    
      myTestTheFilterVariableName = actualFilterNameFilter;
    
    })); // This is where you actually include the filter for testing.
         // Use the underscores if your variable name is the exact same as the injected parameter.
         // This is where you would use your variable name from above.
    
    
      it('should do something here', function(){
        expect(myTestTheFilterVariableName(filterParameter)).toEqual(expectedResultHere);
      });
    });
    

    【讨论】:

      【解决方案5】:

      这里有一个可运行的过滤器测试示例。

      angular.module('myModule', []).filter('multiplier', function() {
        return function(number, multiplier) {
          if (!angular.isNumber(number)) {
            throw new Error(number + " is not a number!");
          }
          if (!multiplier) {
            multiplier = 2;
          }
          return number * multiplier;
        }
      });
      
      describe('multiplierFilter', function() {
        var filter;
      
        beforeEach(function() {
          module('myModule');
          inject(function(multiplierFilter) {
            filter = multiplierFilter;
          });
        });
      
        it('multiply by 2 by default', function() {
          expect(filter(2)).toBe(4);
          expect(filter(3)).toBe(6);
        });
      
        it('allow to specify custom multiplier', function() {
          expect(filter(2, 4)).toBe(8);
        });
      
        it('throws error on invalid input', function() {
          expect(function() {
            filter(null);
          }).toThrow();
        });
      });
      <link href="https://cdnjs.cloudflare.com/ajax/libs/jasmine/2.4.1/jasmine.css" rel="stylesheet"/>
      <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular.min.js"></script>
      <script src="https://cdnjs.cloudflare.com/ajax/libs/jasmine/2.4.1/jasmine.js"></script>
      <script src="https://cdnjs.cloudflare.com/ajax/libs/jasmine/2.4.1/jasmine-html.js"></script>
      <script src="https://cdnjs.cloudflare.com/ajax/libs/jasmine/2.4.1/boot.js"></script>
      <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.8/angular-mocks.js"></script>

      注意:此答案是在 the SO Documentation Sunset 之后创建的,基于 AngularJS 单元测试过滤器示例和关于 Meta 的建议,即所有有价值的文档内容都应转换为答案。

      【讨论】:

        猜你喜欢
        • 2014-04-30
        • 1970-01-01
        • 2014-09-21
        • 2014-04-06
        • 1970-01-01
        • 2012-08-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多