【问题标题】:How to write angularjs unit test for interval which is in a run block如何为运行块中的间隔编写angularjs单元测试
【发布时间】:2017-12-20 18:13:00
【问题描述】:

我正在为 $interval 编写单元测试。代码是这样的: angular.module('serviceInvoker', []).

run(function($rootScope, $http, $interval, DateTimeFormatter) {
    $rootScope.loadData = function(serviceName, dataName) {
        $http.get(serviceName)
            .then(function(result) {
                serviceSuccessFunc(result, dataName)
            })
            .catch(function(error) {
                serviceErrorFunc(error, dataName)
            });

        $rootScope.current = moment().toISOString();
        $rootScope.now = moment($rootScope.current).format(DateTimeFormatter.DayHoursFormat); 
    };

    $rootScope.autoRefresh = function(serviceName, dataName, interval) {
        $interval(function() {
            $rootScope.loadData(serviceName, dataName)
        }, interval);
    };

    var serviceSuccessFunc = function(result, dataName) {
        $rootScope[dataName] = result.data;
    };

    var serviceErrorFunc = function(error, dataName) { 
        $rootScope[dataName] = error;
    };
});

测试代码是这样的:

describe('serviceInvoker', function() {

beforeEach(module('serviceInvoker'));
beforeEach(module(function($provide) {
    $provide.value('DateTimeFormatter', {
        DayHoursFormat: 'HH:mm'
    });

    $provide.value('serviceSuccessFunc', jasmine.createSpy());
    $provide.value('serviceErrorFunc', jasmine.createSpy());
}));
var $interval;
beforeEach(inject(function (_$rootScope_, _$interval_, _serviceSuccessFunc_, _serviceErrorFunc_) {
    $rootScope = _$rootScope_;
    scope = $rootScope.$new();
    $interval = _$interval_;
    serviceSuccessFunc = _serviceSuccessFunc_;
    serviceErrorFunc = _serviceErrorFunc_;
}));

 describe("loadData function ", function () {

    it("should expose loadData function to $rootScope", function () {
        expect(angular.isFunction($rootScope.loadData)).toBe(true);
    });

    it("should be called", inject(function($http) {
        spyOn($rootScope, 'loadData');
        $rootScope.loadData('service', 'data');
        expect($rootScope.loadData).toHaveBeenCalledWith('service', 'data');
    }));
});

 describe("autoRefresh function ", function () {

    it("should expose autoRefresh function to $rootScope", function () {
        expect(angular.isFunction($rootScope.autoRefresh)).toBe(true);
    });

    it("should be called", function() {
        var $intervalspy = jasmine.createSpy('$interval', $interval); 
        spyOn($rootScope, 'autoRefresh').and.callThrough();

        $rootScope.autoRefresh('service', 'data','interval');
        expect($rootScope.autoRefresh).toHaveBeenCalledWith('service', 'data', 'interval');  

        expect($intervalspy).toHaveBeenCalled();
        // expect($intervalspy).toHaveBeenCalledWith(jasmine.any(Function), 1000);
    });
});

});

但是interval有一个错误:Error: Expected spy $interval to has been called.

我不知道如何为函数内部(在运行块中)的间隔编写单元测试,谁能给我一些帮助?

【问题讨论】:

    标签: angularjs unit-testing jasmine intervals


    【解决方案1】:

    $intervalspy 仅用于测试本身。它没有被调用。

    与任何其他经过测试的服务一样,$interval 应该被监视、模拟或存根。可以使用 that 之类的装饰器来窥探它,并且存根更简单:

    beforeEach(() => {
      module({ $interval: jasmine.createSpy() })
    });
    
    ...
    $rootScope.autoRefresh('service', 'data', 'interval');
    expect($interval).toHaveBeenCalledWith(jasmine.any(Function), 'interval');
    expect($rootScope.loadData).not.toHaveBeenCalled(), 
    
    var intervalCallback = $interval.calls.first().args[0];
    intervalCallback();
    expect($rootScope.loadData).toHaveBeenCalledWith(...), 
    

    【讨论】:

    • 非常感谢,但我不明白是什么: beforeEach(() => { module({ $interval: jasmine.createSpy() }) });我应该在哪里定义它?我是 angularjs 的新手。谢谢!
    • 您应该在与其他 beforeEach 块相同的位置定义它。
    • 这样吗? beforeEach(inject(function ($rootScope, $interval, serviceSuccessFunc, serviceErrorFunc) { $rootScope = $rootScope; 范围 = $rootScope.$new(); $interval = $interval; serviceSuccessFunc = serviceSuccessFunc; serviceErrorFunc = serviceErrorFunc i>; $interval = jasmine.createSpy(); }));
    • beforeEach 带有module 的块应该在带有inject 的块之前。你已经有了beforeEach(module(...)) 块。您可以在那里添加另一个。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多