当 运行 Karma 测试时,$provide 不是一个函数

$provide is not a function when running a Karma test

我想测试 angular 服务。使用 karma 执行测试时出现错误:

Error: [$injector:modulerr] Failed to instantiate module function ($provide) due to:
    TypeError: $provide is not a function
        at K:/home/projects/tmp/mobile/test/myservice.Spec.js:24:4
        at Object.invoke (K:/home/projects/tmp/mobile/vendor/angular/angular.js:4203:17)
        at K:/home/projects/tmp/mobile/vendor/angular/angular.js:4120:45
        at forEach (K:/home/projects/tmp/mobile/vendor/angular/angular.js:323:20)
        at loadModules (K:/home/projects/tmp/mobile/vendor/angular/angular.js:4099:5)
        at Object.createInjector [as injector] (K:/home/projects/tmp/mobile/vendor/angular/angular.js:4025:11)
        at Object.workFn (K:/home/projects/tmp/mobile/vendor/angular-mocks/angular-mocks.js:2425:52)

        at forEach (K:/home/projects/tmp/mobile/vendor/angular/angular.js:323:20)
        at loadModules (K:/home/projects/tmp/mobile/vendor/angular/angular.js:4099:5)
        at Object.createInjector [as injector] (K:/home/projects/tmp/mobile/vendor/angular/angular.js:4025:11)
        at Object.workFn (K:/home/projects/tmp/mobile/vendor/angular-mocks/angular-mocks.js:2425:52)
        at K:/home/projects/tmp/mobile/vendor/angular/angular.js:63:12
        at K:/home/projects/tmp/mobile/vendor/angular/angular.js:4138:15
    TypeError: Cannot read property 'getData' of undefined
        at Object.<anonymous> (K:/home/projects/tmp/mobile/test/myservice.Spec.js:38:11)

我想测试该服务的 getDatagetData 首先检查数据是否在缓存中,如果不在则调用服务器检索数据。 Dashboards 只是由 Restangular 创建的服务。

var services = angular.module('services.dashboards', ['models.dashboards', 'models.metrics', 'LocalStorageModule', 'app.filters']);

services.factory('DashboardsService', ['Restangular', '$q', 'Metrics', 'Dashboards', 'localStorageService', '$filter', 'filterByGradedFilter', function (Restangular, $q, Metrics, Dashboards, localStorageService, $filter, filterByGradedFilter) {
    var factory = {};

    factory.getData = function () {
        var defer = $q.defer();
        var data = localStorageService.get('data');
        if (data === undefined) {
            Dashboards.post()
                .then(function (result) {
                    return Restangular.oneUrl('newDash', result.data).get();
                })
                .then(function (result) {
                    data = result.data;
                    localStorageService.set('data', data);
                    defer.resolve(data);
                });
        } else {
            defer.resolve(data);
        }
        return defer.promise;
    }

    return factory;

}]);

在测试中,我使用 sinon 模拟 RestangularDashboards

describe('Dashboards Service', function () {

    // Holds the service under test
    var service;

    beforeEach(module('services.dashboards'));

    // Mocks
    var mockRestangular;
    var mockDashboards;
    beforeEach(function () {
        mockRestangular = sinon.stub({
            oneUrl: function () {

            }
        });
        var expectedResponse = '{ dashid: xxxx}';
        mockDashboards = sinon.stub({
            post: function () {
                return when(expectedResponse);
            }
        })
        module(function ($provide) {
            $provide('Restangular', mockRestangular);
            $provide('Dashboards', mockDashboards);
        })

    });

    // We inject the service
    beforeEach(inject(function (_DashboardsService_) {
        service = _DashboardsService_;
    }));

    describe('#getData', function () {
        it('should get a dashboard', function () {
            console.log(service);
            service.getData().then(function (result) {
                console.log(result);
                expect(result).toEqual({});
            })
        })
    })
})

它是以下之一

$provide.value('...', {})
$provide.constant('...', {})
$provide.service('...', {})
$provide.factory('...', {})
$provide.decorator('...', {})
$provide.provider('...', {})