0

我有一个 Angular 服务的单元测试,我在其中测试缓存 $cacheFactory 在调用 save() 方法后是否被清除,该方法将 http post 发送到后端。在 1.0.7 中,此测试在 Karma 和 Jasmine Specrunner.html 中通过,但在迁移到 Angular 1.2.0 后它失败了。我没有更改服务或规范文件中的任何代码。当我手动检查时,缓存在生产中被清除。有任何想法吗?

编辑: 错误的行动: http ://plnkr.co/edit/1INhdM

错误信息是:

现场服务 save() 应该从缓存中清除字段数组。

Expected 2 to be 1.
Error: Expected 2 to be 1.
at new jasmine.ExpectationResult (http://localhost:1234/js/test/lib/jasmine/jasmine.js:114:32)
at null.toBe (http://localhost:1234/js/test/lib/jasmine/jasmine.js:1235:29)
at http://localhost:1234/js/test/spec/field-serviceSpec.js:121:25
at wrappedCallback (http://localhost:1234/js/angular-1.2.0.js:10549:81)
at http://localhost:1234/js/angular-1.2.0.js:10635:26
at Scope.$eval (http://localhost:1234/js/angular-1.2.0.js:11528:28)
at Scope.$digest (http://localhost:1234/js/angular-1.2.0.js:11373:31)
at Scope.$delegate.__proto__.$digest (<anonymous>:844:31)
at Scope.$apply (http://localhost:1234/js/angular-1.2.0.js:11634:24)
at Scope.$delegate.__proto__.$apply (<anonymous>:855:30)

我正在测试的服务:

angular.module('services.field', [])
.factory('Field', ['$http', '$cacheFactory', function ($http, $cacheFactory) {

var fieldListCache = $cacheFactory('fieldList');

var Field = function (data) {
    angular.extend(this, data);
};

// add static method to retrieve all fields
Field.query = function () {
    return $http.get('api/ParamSetting', {cache:fieldListCache}).then(function (response) {
        var fields = [];
        angular.forEach(response.data, function (data) {
            fields.push(new Field(data));
        });
        return fields;
    });
};

// add static method to retrieve Field by id
Field.get = function (id) {
    return $http.get('api/ParamSetting/' + id).then(function (response) {
        return new Field(response.data);
    });
};

// add static method to save Field
Field.prototype.save = function () {
  fieldListCache.removeAll();
    var field = this;
    return $http.post('api/ParamSetting', field ).then(function (response) {
        field.Id = response.data.d;
        return field;
    });
};

return Field;
}]);

失败的单元测试:

'use strict';

describe('Field service', function() {
var Field, $httpBackend;

  // load the service module
beforeEach(module('services.field'));

// instantiate service
beforeEach(inject(function(_Field_, _$httpBackend_) {
    Field = _Field_;
    $httpBackend = _$httpBackend_;
}));

afterEach(function() {
    $httpBackend.verifyNoOutstandingExpectation();
    $httpBackend.verifyNoOutstandingRequest();
});

describe("save()", function() {

    it('should clear field array from cache', function () {
        var firstMockData = [{ Alias: 'Alias 1' }, { Alias: 'Alias 2' }];
        var secondMockData = [{ Alias: 'Alias 3' }];
        var newField = new Field({});
        var counter = 0;

        $httpBackend.when('GET', 'api/ParamSetting').respond(function () {
            // return firstMockData on first request and secondMockdata on subsequent requests
            if (counter === 0) {
                counter++;
                return [200, firstMockData, {}];
            } else {
                return [200, secondMockData, {}];
            }
        });

        $httpBackend.when('POST', 'api/ParamSetting').respond({});

        // query fields 
        Field.query();

        // save new field
        newField.save();

        // query fields again
        Field.query().then(function (data) {
            expect(data.length).toBe(secondMockData.length);
            expect(data[0].Alias).toBe(secondMockData[0].Alias);
        });

        $httpBackend.flush();
    });

});
});
4

2 回答 2

0

答案是我错误地期望异步请求以特定顺序返回响应,并且我的请求被缓存,直到我调用 $httpBackend.flush() 这将导致 .query() 只被调用一次。为了使其工作,可以通过在第一个 query() 调用之后添加另一个刷新来使调用同步:http ://plnkr.co/edit/MzuplQnkQunDyvy6vCvy?p=preview

于 2013-11-22T19:52:19.770 回答
0

以下代码将允许您在单元测试中模拟 $cacheFactory。$provide 服务将允许服务依赖注入使用您的 $cacheFactory 而不是默认的 $cacheFactory。

var cache, $cacheFactory; //used in your its
beforeEach(function(){
    module(function ($provide) {
        $cacheFactory = function(){};
        $cacheFactory.get = function(){};

        cache = {
            removeAll: function (){}
        };
        spyOn(cache, 'removeAll');
        spyOn($cacheFactory, 'get').and.returnValue(cache);

        $provide.value('$cacheFactory', $cacheFactory);
    });
});

describe('yourFunction', function(){
    it('calls cache.remove()', function(){
        yourService.yourFunction();
        expect(cache.remove).toHaveBeenCalled();
    });
});
于 2015-04-03T05:21:19.767 回答