如何模拟单元测试的angularJs过滤器值

时间:2017-04-13 15:52:47

标签: angularjs unit-testing jasmine angular-filters

我正在使用翻译过滤器对控制器中的功能进行单元测试 我想用自定义值来模拟过滤器 我使用$provide来模拟一个值,但它什么也没做 有什么建议吗? 非常感谢你

我的控制器:

    function MainCtrl($scope,$filter){
        $scope.onDateChange = onDateChange;

        var date = new Date();
        var date_format_filter = $filter("i18nFilter")("DATE_FORMAT_FILTER");
        // i want this to be dd/mm/yyyy
        var date_format_moment = $filter("i18nFilter")("DATE_FORMAT_MOMENT");
         // i want this to be DD/MM/YYYY
        console.log("DATE FORMAT" , date_format_moment); // print DATE_FORMAT_MOMENT in unit test = test fail
        $scope.startDate = $filter('date')(date , date_format_filter);
        $scope.endDate = $filter('date')(date , date_format_filter);

        function onDateChange(whichDate){

            var startDateFormatted = moment($scope.startDate , date_format_moment).startOf('day').toDate();
            var endDateFormatted =  moment($scope.endDate, date_format_moment).startOf('day').toDate();
                if(startDateFormatted.getTime() > endDateFormatted.getTime()){
                    $scope.startDateError = true;
                    $scope.errorLabel = $filter("i18nFilter")("DATE_START_ERROR");
                }else {
                    $scope.monitoring.startDateError = false;
                }
         }
    }

我的单元测试

describe('CONTROLLER : MainCtrl', function() {  


    // MAIN VARIABLES ==================================================================
    var $scope,
        $controller,
        $rootScope,
        $filter;


    // LOAD APP MODULE =================================================================
    beforeEach(module('myApp'));


    // SETUP ===========================================================================
    beforeEach(function() {

        module(function($provide) {
            $provide.value('i18nFilter', 'DD/MM/YYYY');
        });

         inject(function ($rootScope , _$controller_ , $injector) {
                $scope          = $rootScope.$new();
                $filter = $injector.get("$filter");
                $controller     = _$controller_;
                $controller = $controller('MainCtrl' , {$scope : $scope  , $filter : $filter});
         });
    });

    // Controller initialization -------------------------------------------------------
    it('- Controller should be defined.', function() {
        expect($controller).toBeDefined();
    });

    it('- Should test startDate change event KO .', inject(function($controller){
        var date_format_moment = 'DD/MM/YYYY';
        $scope.startDate = moment(new Date()).add(1, 'days').format(date_format_moment);
        $scope.endDate = moment(new Date()).format(date_format_moment);
        $scope.onDateChange('startDate');
        expect($scope.startDateError).toEqual(true);
    }));
});

1 个答案:

答案 0 :(得分:1)

过滤器是一种功能,过滤器服务后缀为Filter,因此它应为i18nFilterFilter

beforeEach(module({ i18nFilterFilter: jasmine.createSpy() }));

...
i18nFilterFilter.and.returnValues('dd/mm/yyyy', 'DD/MM/YYYY');

更简洁的方法是减少移动部件的数量并模拟$filter本身,

beforeEach(module({ $filter: jasmine.createSpy() }));

...
var i18nFilterMock = jasmine.createSpy().and.returnValues('dd/mm/yyyy', 'DD/MM/YYYY');
var dateFilterMock = ...;

$filter.and.returnValues(i18nFilterMock, i18nFilterMock, dateFilterMock, dateFilterMock);

...
var ctrl =  $controller('MainCtrl', ...);

expect($filter.calls.count()).toBe(4);
expect($filter.calls.allArgs()).toEqual([
  ['i18nFilter'], ['i18nFilter'], ['date'], ['date']
]);

expect(i18nFilterMock.calls.count()).toBe(2);
expect($filter.calls.allArgs()).toEqual([
  ['DATE_FORMAT_FILTER'], ['DATE_FORMAT_MOMENT']
]);

值得一提的是,Sinon为“智能”提供了更多功能。存根/间谍比Jasmine,所以两者可以一起使用。

相关问题