如何使用 Karma 和 Sinon 监视 Angular 过滤器
How to spy on an Angular filter using Karma and Sinon
如果我有这样的服务和过滤器:
angular.module('myApp', [])
.filter('myFilter', [function() {
return function() { return 1; };
}])
.service('myServiceWhichCallsMyFilter', ['$filter', function($filter) {
this.callTheFilter = $filter('myFilter');
}]);
和这样的测试:
describe('myFilterTest', function() {
var $filter;
beforeEach(module('myApp'));
beforeEach(inject(function (_$filter_) {
$filter = _$filter_;
}));
it('should filter correctly', function() {
var filteredValue = $filter('myFilter')(100);
expect(filteredValue).to.equal(1); // passes
});
});
describe('myServiceTest', function() {
var myServiceWhichCallsMyFilter;
var myFilterSpy = sinon.spy();
beforeEach(module('myApp'));
beforeEach(module(function ($provide) {
$provide.value('myFilter', myFilterSpy);
}));
beforeEach(inject(function (_myServiceWhichCallsMyFilter_) {
myServiceWhichCallsMyFilter = _myServiceWhichCallsMyFilter_;
}));
it('should call myFilter', function() {
myServiceWhichCallsMyFilter.callTheFilter();
expect(myFilterSpy.callCount).to.equal(1); // fails - callCount is 0
});
});
...我怎样才能让第二个测试通过?在那次测试中,我只对服务是否调用过滤器感兴趣(而不是过滤器的正确性,我单独测试),所以我想模拟它。但是$provide.value('myFilter', myFilterSpy)
好像不行。
angular.module('myApp', [])
.filter('myFilter', [function() {
return function() { return 1; };
}])
.service('myServiceWhichCallsMyFilter', ['$filter', function($filter) {
this.callTheFilter = $filter('myFilter');
}]);
看,您的服务实际上并没有调用 $filter,它只是实例化它。
按如下方式更改行,您的测试将 'pass',尽管您正在更改行为,所以...弄清楚您想要它做什么
this.callTheFilter = $filter('myFilter')(100);
知道了:在第二次测试中,我需要 $provide
我的间谍过滤器 myFilterFilter
:
describe('myServiceTest', function() {
var myServiceWhichCallsMyFilter;
var myFilterSpy = sinon.spy();
beforeEach(module('myApp'));
beforeEach(module(function ($provide) {
$provide.value('myFilterFilter', myFilterSpy );
}));
beforeEach(inject(function (_myServiceWhichCallsMyFilter_) {
myServiceWhichCallsMyFilter = _myServiceWhichCallsMyFilter_;
}));
it('should call myFilter', function() {
expect(myFilterSpy.callCount).to.equal(0); // callTheFilter has not been called!
myServiceWhichCallsMyFilter.callTheFilter();
expect(myFilterSpy.callCount).to.equal(1); // passes
});
});
这实际上在文档中提到:"Notice that the suffix 'Filter' is appended to your filter name when injected"。
如果我有这样的服务和过滤器:
angular.module('myApp', [])
.filter('myFilter', [function() {
return function() { return 1; };
}])
.service('myServiceWhichCallsMyFilter', ['$filter', function($filter) {
this.callTheFilter = $filter('myFilter');
}]);
和这样的测试:
describe('myFilterTest', function() {
var $filter;
beforeEach(module('myApp'));
beforeEach(inject(function (_$filter_) {
$filter = _$filter_;
}));
it('should filter correctly', function() {
var filteredValue = $filter('myFilter')(100);
expect(filteredValue).to.equal(1); // passes
});
});
describe('myServiceTest', function() {
var myServiceWhichCallsMyFilter;
var myFilterSpy = sinon.spy();
beforeEach(module('myApp'));
beforeEach(module(function ($provide) {
$provide.value('myFilter', myFilterSpy);
}));
beforeEach(inject(function (_myServiceWhichCallsMyFilter_) {
myServiceWhichCallsMyFilter = _myServiceWhichCallsMyFilter_;
}));
it('should call myFilter', function() {
myServiceWhichCallsMyFilter.callTheFilter();
expect(myFilterSpy.callCount).to.equal(1); // fails - callCount is 0
});
});
...我怎样才能让第二个测试通过?在那次测试中,我只对服务是否调用过滤器感兴趣(而不是过滤器的正确性,我单独测试),所以我想模拟它。但是$provide.value('myFilter', myFilterSpy)
好像不行。
angular.module('myApp', [])
.filter('myFilter', [function() {
return function() { return 1; };
}])
.service('myServiceWhichCallsMyFilter', ['$filter', function($filter) {
this.callTheFilter = $filter('myFilter');
}]);
看,您的服务实际上并没有调用 $filter,它只是实例化它。
按如下方式更改行,您的测试将 'pass',尽管您正在更改行为,所以...弄清楚您想要它做什么
this.callTheFilter = $filter('myFilter')(100);
知道了:在第二次测试中,我需要 $provide
我的间谍过滤器 myFilterFilter
:
describe('myServiceTest', function() {
var myServiceWhichCallsMyFilter;
var myFilterSpy = sinon.spy();
beforeEach(module('myApp'));
beforeEach(module(function ($provide) {
$provide.value('myFilterFilter', myFilterSpy );
}));
beforeEach(inject(function (_myServiceWhichCallsMyFilter_) {
myServiceWhichCallsMyFilter = _myServiceWhichCallsMyFilter_;
}));
it('should call myFilter', function() {
expect(myFilterSpy.callCount).to.equal(0); // callTheFilter has not been called!
myServiceWhichCallsMyFilter.callTheFilter();
expect(myFilterSpy.callCount).to.equal(1); // passes
});
});
这实际上在文档中提到:"Notice that the suffix 'Filter' is appended to your filter name when injected"。