如何在 AngularJS 1.x 中对过滤器进行单元测试
Posted
技术标签:
【中文标题】如何在 AngularJS 1.x 中对过滤器进行单元测试【英文标题】:How to unit test a filter in AngularJS 1.x 【发布时间】:2014-02-01 09:25:10 【问题描述】:如何在 Angular 中对过滤器进行单元测试?
【问题讨论】:
egghead.io/lessons/angularjs-testing-overview docs.angularjs.org/guide/dev_guide.unit-testing @michael,您提供的链接似乎已损坏。 docs.angularjs.org/guide/unit-testing 【参考方案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】:除了注入实际的$filter
service 之外,还有其他方法可以测试过滤器。
例子:
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 的建议,即所有有价值的文档内容都应转换为答案。
【讨论】:
以上是关于如何在 AngularJS 1.x 中对过滤器进行单元测试的主要内容,如果未能解决你的问题,请参考以下文章