AngularJS指令测试未知提供程序:translateFilterProvider

时间:2015-08-10 11:14:51

标签: javascript angularjs unit-testing angularjs-directive

嗨,大家好!

首先,很抱歉为此问题创建了一个新问题,但我是网站上的新用户,我还无法发表评论。尽管我已经在这个网站上找到了我可以使用的答案的问题,但我遇到了另一个问题。

我正在测试一个具有翻译功能的应用程序,它给了我一个错误:

未知提供商:translateFilterProvider< - translateFilter

我的指示如下:

CF-toplist-card.js

angular.module('cfPresentation.directives')
.directive('cfToplistCard',
[
'CFToplistCardController',
function(CFToplistCardController) {
    return {
        restrict: 'E',
        transclude: true,
        scope: {
            cfCardId: '=',
            cfRank: '=',
            cfColor: '=',
            cfId: '=',
            cfName: '=',
            cfPicUrl: '=',
            cfCurrentValueDesc: '=',
            cfCurrentValue: '=',
            cfTargetValue: '=',
            cfChange: '='        
        },
        controllerAs: 'vm',
        require: ['cfToplistCard'],
        bindToController: true,
        controller: CFToplistCardController,
        templateUrl: 'src/presentation/directives/toplistcard/cf-toplist-card.html',
        link: function(scope, element, attrs, controllers) {
            var vm = controllers[0];
        }
    };
}
])
.factory('CFToplistCardController',['$timeout', function($timeout) {
    function CFToplistCardController($element, $scope) {
       var vm = this;

       vm.element = $element;

       $scope.$on('$destroy', function() {
           delete vm.element;
       });
    }   

    CFToplistCardController.$inject = ['$element', '$scope'];

    return CFToplistCardController;
}]
);

CF-toplist-card.html

<div id="{{ vm.cfCardId }}" class="cf-toplist-card col-xs-12 col-md-12 col-lg-12">
    <div class="toplist row">
        <!--{{vm.cfColor}} should be used for border color!!! -->
        <div class="col-xs-6 col-md-2 col-lg-2 toplist-col1" style="border-left-color: {{vm.cfColor}}">
            <h1>{{vm.cfRank}}</h1>
        </div>
        <div class="col-xs-6 col-md-2 col-lg-2 toplist-col2">
            <div class="toplist-picture-block">
                <i class="toplist-picture-bg toplist-picture-radius"></i>
                <img alt=" " class="toplist-picture toplist-picture-radius" ng-src="{{ $root.backendBaseURL + vm.cfPicUrl + vm.cfId}} "/>
            </div>
        </div>
        <div class="col-xs-6 col-sm-6 col-md-4 col-lg-4 toplist-data">
            <div class="toplist-name toplist-value">
                {{vm.cfName}}
            </div>
            <div class="toplist-desc">
                {{ 'common.target' | translate }}
            </div>
            <div class="toplist-value">
                {{ vm.cfTargetValue | cfNumberFormat }}
            </div>
        </div> 
        <div class="col-xs-6 col-sm-6 col-md-4 col-lg-4 toplist-data toplist-float-right-td">
            <div class="toplist-desc">
                {{vm.cfCurrentValueDesc}}
            </div>
            <div class="toplist-value highlight">
                {{ vm.cfCurrentValue | cfNumberFormat }}
            </div>
            <div class="toplist-desc">
                {{ 'common.change' | translate }}
            </div>
            <div class="toplist-value">
                {{ vm.cfChange | cfNumberFormat }}
            </div>
        </div> 
    </div>
</div>     

我写的测试看起来像这样:

describe("test.spec.presentation.directives.toplistcard.cf-toplist-card", function () {

    var toplistController;
    var element;
    var $scope;
    var http;
    var template1;
    var url1 = "src/presentation/directives/toplistcard/cf-toplist-card.html";
    var $timeout;
    var $compile;
    var cache;

    beforeEach(module("cfPresentation.directives"));
    beforeEach(angular.mock.module("cfPresentation.services"));
    beforeEach(angular.mock.module("cfPresentation.filters"));
    beforeEach(angular.mock.module('ui.router'));
    var mockTranslateFilter;

    beforeEach(function() {
        module(function($provide) {
            $provide.value('translateFilter', mockTranslateFilter);
        });

        mockTranslateFilter = function(value) {
            return value;
        };
    });
    beforeEach(module('templates'));

    beforeEach(angular.mock.inject(['$timeout','$injector', '$compile', '$rootScope',  '$templateCache', function(_$timeout_, $injector,_$compile_, $rootScope, $templateCache) {
        $scope = $rootScope;
        $timeout = _$timeout_;
        http = $injector.get('$httpBackend');
        $compile = _$compile_;
        cache = $templateCache;

        element = $compile("<cf-toplist-card></cf-toplist-card>")($scope);

        template1 = cache.get('app/src/presentation/directives/toplistcard/cf-toplist-card.html');

        http.when('GET', url1).respond(template1);

        http.flush(); 

        $scope.$apply();
    }]));

    describe('CFToplistCardController', function() {
        beforeEach(function() {
            toplistController = element.find('.cf-toplist-card').controller('cfToplistCard');
        });

        it('should be defined', function() {
            expect(toplistController).toBeDefined();
        });

        it('should destroy on scope destroy', function() {
            expect(toplistController.element).toBeDefined();
            var isolateScope = element.find('.cf-toplist-card').scope();
            isolateScope.$destroy();
            expect(toplistController.element).not.toBeDefined();
        });
    });
});

所以我一直在阅读本网站上的文章,我找到了一些问题here的解决方案。这已经在我上面的测试代码中使用了,它运行成功(我已经尝试了很多东西,但这是唯一使我的测试运行的东西)。

我唯一的问题是,我必须在提交之前运行 eslint 语法检查,它会给我一个错误你应该使用数组语法对于DI 。 我知道这是一个微不足道的问题,但即使在我阅读了Angular Docs并尝试了数千种实现类型之后,我找不到合适的解决方案,如果没有这个,我就无法继续。

因此,为了使我的问题更具体:我需要使用依赖注入的数组语法注入此转换,而不是:

var mockTranslateFilter;

    beforeEach(function() {
        module(function($provide) {
            $provide.value('translateFilter', mockTranslateFilter);
        });

        mockTranslateFilter = function(value) {
            return value;
        };
    });

非常感谢任何帮助!

谢谢, Szkíta

1 个答案:

答案 0 :(得分:1)

所以经过几个小时的绝望之后,我找到了一个解决方案:

beforeEach(function() {
    module(['$provide', function($provide) {
        $provide.value('translateFilter', [function(value) {
            return value;
        }][0]
        );
    }]);
});

问题是eslint需要DI的数组语法,但实际的功能没有正确执行,它总是给我一个... is not a function错误。所以在工作解决方案中,我将函数放在一个数组中,然后我用[0]将它从它中取出,所以每个人都很高兴。