Angular Karma单元测试控制器没有注入模拟服务依赖性

时间:2015-06-16 15:49:47

标签: angularjs unit-testing dependency-injection karma-jasmine

我尝试了各种方法来实例化模拟服务' listFilterManager'并将其传递给控制器​​。尽管创建并访问了模拟服务,但是当执行范围。$ digest()时,将运行实际的非模拟服务而不是模拟的listFilterManager。更令人困惑的是,resourceStore服务被正确地模拟和注入。任何帮助将不胜感激。

相关代码:

    beforeEach(function(){
        module('listModule');
        module(function($provide){
            $provide.factory('resourceStore', function(){
                return {
                    alertsArray: Object.keys(mockData).map(function(key){
                        return mockData[key];
                    })
                };
            });
            $provide.value('listFilterManager',{
                filterList: jasmine.createSpy('filterList').and.callFake(function(input){
                    return input;
                })
            });
        });
    });

    describe('instantiates the Alert List Ctrl', function(){
        var scope, listFilterParams, listFilterManager, resourceStore, tableAccessorDictionaries, AlertListCtrl;
        beforeEach(function(){
            inject(function(_$rootScope_, $controller, _tableAccessorDictionaries_, _listFilterParams_, _resourceStore_, _listFilterManager_){
                scope = _$rootScope_.$new();
                listFilterParams = _listFilterParams_;
                listFilterManager = _listFilterManager_; //this refs the mocked service, but the actual service is the one that is executed.
                var deps = {
                    '$scope': scope,
                    'tableAccessorDictionaries': _tableAccessorDictionaries_,
                    'listFilterManager': _listFilterManager_,
                    'listFilterParams': _listFilterParams_,
                    'resourceStore': _resourceStore_
                };
                AlertListCtrl = $controller('AlertListCtrl', deps);
            });
        });

        it('it should filter the list when a list filter parameter changes', function(){
            expect(listFilterManager.filterList).not.toHaveBeenCalled();
            scope.filterParams.text = 'This is a test query';
            scope.$digest();
            expect(listFilterManager.filterList).toHaveBeenCalled();
        });

    });

2 个答案:

答案 0 :(得分:0)

所以你说' listFilterManager'是一个服务,但在beforeEach方法中,您将其作为值提供。您需要将其作为工厂提供,以便对其进行适当的模拟。替换以下

               $provide.value('listFilterManager',{
            filterList: jasmine.createSpy('filterList').and.callFake(function(input){
                return input;
            })
        });

使用:

               $provide.factory('listFilterManager', function () {
                 return {
                   filterList: jasmine.createSpy('filterList').and.callFake(function(input){
                     return input;
                 };
               })
        });

它应该可以正常工作。

答案 1 :(得分:0)

过了一段时间我才明白了。问题是因为我测试的函数是从underscore.debounce包装器中调用的。辩论显然导致测试问题,如 here 所述。解决方案是在测试文件中重新定义_.debounce(归功于上述帖子):

-12780

哇,这是一个多么令人沮丧的问题,但希望这会帮助其他有需要的人!