0

バックエンドへの http 投稿を行う save() メソッドの呼び出しが行われた後、キャッシュ $cacheFactory がクリアされることをテストする Angular サービスの単体テストがあります。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() が 1 回しか呼び出されないことです。これを機能させるには、最初の 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 に答える