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);
});
source to share
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.
source to share