Jasmine test using spyon with $ httpBackend not working

I am trying to write a jasmine test in some javascript using spyon over a method that uses $ http. I mocked this using $ httpBackend and unfortunately the spy doesn't seem to pick up on the fact that the method was actually called post $ http useage. I can see that it is being called in debug, so not sure why it is reporting that it has not been called. I suspect I am having a problem using my application? or order $ httpBackend.flush \ verify ?:

Verifiable code

function FileUploadController($scope, $http, SharedData, uploadViewModel) {

   Removed variables for brevity
   .....

    $scope.pageLoad = function () {
        $scope.getPeriods();

        if ($scope.uploadViewModel != null && $scope.uploadViewModel.UploadId > 0) {
            $scope.rulesApplied = true;
            $scope.UploadId = $scope.uploadViewModel.UploadId;

            $scope.linkUploadedData();
        } else {
            $scope.initDataLinkages();
        }

    }


    $scope.initDataLinkages = function () {

        $http({ method: "GET", url: "/api/uploadhistory" }).
           success(function (data, status) {
               $scope.status = status;
               $scope.setUploadHistory(data);

           }).
         error(function (data, status) {
             $scope.data = data || "Request failed";
             $scope.status = status;
         });

    }

    $scope.setUploadHistory = function (data) {

        if ($scope.UploadId > 0) {
            $scope.currentUpload = data.filter(function (item) {
                return item.UploadId === $scope.UploadId;
            })[0];

            //Remove the current upload, to prevent scaling the same data!
            var filteredData = data.filter(function (item) {
                return item.UploadId !== $scope.UploadId;
            });
            var defaultOption = {
                UploadId: -1,
                Filename: 'this file',
                TableName: null,
                DateUploaded: null
            };

            $scope.UploadHistory = filteredData;

            $scope.UploadHistory.splice(0, 0, defaultOption);
            $scope.UploadHistoryId = -1;

            $scope.UploadTotal = $scope.currentUpload.TotalAmount;

        } else {
            $scope.UploadHistory = data;
        }
    }

      

Test setup

beforeEach(module('TDAnalytics'));
beforeEach(inject(function (_$rootScope_, $controller, _$httpBackend_) {
    $rootScope = _$rootScope_;
    $scope = $rootScope.$new();
    $httpBackend = _$httpBackend_;

    var sharedData = { currentBucket: { ID: 1 } };

    controller = $controller('FileUploadController', { $scope: $scope, SharedData: sharedData, uploadViewModel: null }); 

    $httpBackend.when('GET', '/api/Periods').respond(periods);

    $httpBackend.when('GET', '/api/uploadhistory').respond(uploadHistory);


    $scope.mappingData = {
        FieldMappings: [testDescriptionRawDataField, testSupplierRawDataField],
        UserFields: [testDescriptionUserField, testSupplierUserField]
    };
}));

afterEach(function() {
    testDescriptionRawDataField.UserFields = [];
    testSupplierRawDataField.UserFields = [];
    testTotalRawDataField.UserFields = [];

    $httpBackend.flush();
    $httpBackend.verifyNoOutstandingExpectation();
    $httpBackend.verifyNoOutstandingRequest();
});

      

Working test:

it('pageLoad should call linkUploadedData when user has navigated to the page via the Data Upload History and uploadViewModel.UploadId is set', function () {
    // Arrange
    spyOn($scope, 'linkUploadedData');
    $scope.uploadViewModel = {UploadId: 1};
    // Act
    $scope.pageLoad();

    // Assert
    expect($scope.rulesApplied).toEqual(true);
    expect($scope.linkUploadedData.calls.count()).toEqual(1);
});

      

Test that doesn't work (but should return count-0, but is called)

it('pageLoad should call setUploadHistory when data returned successfully', function () {
    // Arrange
    spyOn($scope, 'setUploadHistory');
    // Act
    $scope.initDataLinkages();

    // Assert
    expect($scope.setUploadHistory.calls.count()).toEqual(1);
});

      

+3


source to share


1 answer


The problem is that you are calling httpBackend.flush () after waiting, which means success is called after your tests have run. You must flush before claiming the wait.

it('pageLoad should call setUploadHistory when data returned successfully',
inject(function ($httpBackend, $rootScope) {
    // Arrange
    spyOn($scope, 'setUploadHistory');
    // Act
    $scope.initDataLinkages();
    $httpBackend.flush();
    $rootScope.$digest()
    // Assert
       expect($scope.setUploadHistory.calls.count()).toEqual(1);
}));

      



You may need to remove the flush statement because of your tests, but it probably shouldn't be, because that's usually the bulk of the test behavior and should come before pending assertions.

+2


source







All Articles