如何在AngularJS 1.x中对过滤器进行单元测试

70

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


2
https://egghead.io/lessons/angularjs-testing-overview - Wottensprels
1
http://docs.angularjs.org/guide/dev_guide.unit-testing - michael
@michael,您提供的链接似乎已经失效。 - Richie Thomas
这是Michael可能想要更新的链接:https://docs.angularjs.org/guide/unit-testing。谢谢,C§。 - CSS
5个回答

122

注入 $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更改为:expect(result).to.equal('HELLO WORLD'); - Simon Dragsbæk
1
我不知道在foo后面是否要使用'capitalize'。有人能解释一下它的目的吗? - Winnemucca
1
我已经添加了示例模板语法,这样你就可以看到它来自哪里。它最终只是一个过滤器参数,一些过滤器没有这些参数,但在我看来,这使答案更完整。 - eddiec
这在Chrome上可以运行,但在Firefox或PhantomJS上不行。 - artdias90

12

жӮЁеҸҜд»ҘжіЁе…Ҙ$filter并еҠ иҪҪиҰҒжөӢиҜ•зҡ„иҝҮж»ӨеҷЁгҖӮ然еҗҺпјҢйҖҡиҝҮжӮЁжіЁе…Ҙзҡ„иҝҮж»ӨеҷЁдј йҖ’иҰҒиҝҮж»Өзҡ„еҸӮж•°пјҢ并'expect'жӮЁжүҖйңҖзҡ„з»“жһңгҖӮ

д»ҘдёӢжҳҜзӨәдҫӢпјҡ

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

可以将过滤器注入到测试中(在此找到一段代码片段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');你正在调用整个应用程序,这意味着运行实际的代码。 - Peter MK

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

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>

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


2

除了注入实际的 $filter 服务之外,还有其他测试过滤器的方法。

例如:

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);
  });
});

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接