【问题标题】:How to spy on an Angular filter using Karma and Sinon如何使用 Karma 和 Sinon 监视 Angular 过滤器
【发布时间】:2015-01-10 01:38:55
【问题描述】:

如果我有这样的服务和过滤器:

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) 似乎不起作用。

【问题讨论】:

    标签: angularjs unit-testing karma-runner sinon


    【解决方案1】:
    angular.module('myApp', [])
    
    .filter('myFilter', [function() {
        return function() { return 1; };
    }])
    
    .service('myServiceWhichCallsMyFilter', ['$filter', function($filter) {
        this.callTheFilter = $filter('myFilter');
    }]);
    

    看,你的服务实际上并没有调用 $filter,它只是在实例化它。

    如下更改该行,您的测试将“通过”,尽管您正在更改行为,所以...弄清楚您想要它做什么

    this.callTheFilter = $filter('myFilter')(100);
    

    【讨论】:

    • 不,如果我进行更改,测试不会通过。它在myServiceWhichCallsMyFilter.callTheFilter() 上出错,因为callTheFilter 将被分配给过滤函数的结果:1,它本身不是一个函数。我不希望服务调用过滤器;我希望它公开一个调用过滤器的函数。然后我想测试调用该函数是否会调用过滤器。
    【解决方案2】:

    知道了:在第二个测试中,我需要$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"

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-08-19
      • 2017-12-20
      • 2020-05-23
      • 2016-06-13
      • 1970-01-01
      • 1970-01-01
      • 2016-04-12
      • 2015-05-13
      相关资源
      最近更新 更多