Tech Wizard
Tech Wizard

Reputation: 435

When testing cancelled $http request, $httpBackend.flush(); throws "no pending request to flush"

I implemented canceling http request in my service and I want to test it:

angular.module('EmsWeb.Services').factory('DalService', ['$q', '$http', 'AppModel', 'DalRequestCache', function ($q, $http, appModel, dalRequestCache) {
    return {
        apiUrl: '../api/ModuleApi/',
        viewUrl: '../',
        submitRequestPromise: function (senderIdentifier, url, requestData) {                       
            this.cancelRequest(senderIdentifier);
            var canceler = $q.defer();
            this.addToCache(senderIdentifier, canceler);
              return $http({
                  method: 'POST',
                  url: url,                
                  data: requestData?requestData:null,
                  timeout: canceler.promise
              });           
        },
        addToCache: function (senderIdentifier, canceler) {
            var request = { 'senderIdentifier': senderIdentifier, 'cancelPromise': canceler };
            dalRequestCache.put(senderIdentifier, request);
        },
        cancelRequest: function (senderIdentifier) {
            var request = dalRequestCache.get(senderIdentifier);
            if (request) {
                request.cancelPromise.resolve('canceled');
                dalRequestCache.remove(senderIdentifier);
                return true;
            }
            return false;
        },
 getModules: function (senderIdentifier, appContext, successFn, errorFn) {
            var url = this.apiUrl + 'GetModules';
            var ctx = appModel.context.toRequestContext(appContext);
            this.submitRequest(senderIdentifier, url, ctx, successFn, errorFn);
        }
};
}]);

Here is the test

describe("Unit: Testing Services", function() {

    beforeEach(angular.mock.module('EmsWeb.Services'));
    describe("Unit: DalService", function () {
        var $httpBackend, dalService, appModel;
        beforeEach(inject(function ($q, _$httpBackend_, AppModel, DalService) {
            dalService = DalService;
            appModel = AppModel;
            $httpBackend = _$httpBackend_;
            $httpBackend.when('POST', '../api/ModuleApi/GetModules').respond({ userId: 'userX', 'A-Token': 'xxx' });            
            appModel.context.company = { code: 'LPL' };

        }));

        describe("canceling requests", function () {            
            it('checks request should be canceled ', function () {

                var returnedData;
                var callBackFn = function (data) {
                    returnedData = data;
                };
                dalService.getModules('senderIdentifier', appModel.context, callBackFn, callBackFn);

                var canceled = dalService.cancelRequest('senderIdentifier');
                $httpBackend.flush();
                expect(canceled).to.be.true;
                expect(returnedData).to.undefined;
            });

        });

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

When I run it I am getting "No pending request to flush" error. How do I test that request being canceled for sure if I don't call flush.

Thank you, Alexander

Upvotes: 2

Views: 1537

Answers (1)

alexsanford1
alexsanford1

Reputation: 3727

Instead of calling $httpBackend.flush(), call $rootScope.$digest(). This will force any asynchronous actions (such as promises) to be invoked, and then since the request is cancelled, there will be no http requests to be flushed. I haven't tested this for the code example given here, but it worked in my case.

Upvotes: 4

Related Questions