Here is the question: What is the better way to unit test this specific function? Should all the test items be included in one test or is it better to break up the tests so each test is testing for something more specific?
Function being tested:
$scope.saveFailure = function (response) {
var errs = [];
response.data.forEach((entry) => errs.push("options." + entry.dataField));
if (errs.length > 0) $scope.$emit('datafields:errors', errs);
$scope.gotoTop();
$scope.processing = false;
};
Method 1: Multiple Unit Tests
var mockFailureResponse;
beforeEach(function () {
mockFailureResponse = {
data: [],
};
});
it('saveFailure should set processing to false', function () {
$scope.processing = true;
$scope.saveFailure(mockFailureResponse);
expect($scope.processing).toBe(false);
});
it('saveFailure should call goToTop()', function () {
spyOn($scope, 'gotoTop');
$scope.saveFailure(mockFailureResponse);
expect($scope.gotoTop).toHaveBeenCalled();
});
it('saveFailure should emit datafield errors when present', function () {
spyOn($scope, '$emit');
mockFailureResponse = {
data: [{dataField: "field"}],
};
$scope.saveFailure(mockFailureResponse);
expect($scope.$emit).toHaveBeenCalledWith('datafields:errors', ['options.field']);
});
it('saveFailure should not emit datafield errors non are present', function () {
spyOn($scope, '$emit');
$scope.saveFailure(mockFailureResponse);
expect($scope.$emit.calls.count()).toEqual(0);
});
Method 2: Single Unit Test
it('saveFailure should handle failed requests', function () {
spyOn($scope, '$emit');
let mockFailureResponse = {
data: [],
};
$scope.saveFailure(mockFailureResponse);
expect($scope.$emit.calls.count()).toEqual(0);
mockFailureResponse = {
data: [{ dataField: "field" }],
};
$scope.saveFailure(mockFailureResponse);
expect($scope.$emit).toHaveBeenCalledWith('datafields:errors', ['options.field']);
spyOn($scope, 'gotoTop');
$scope.saveFailure(mockFailureResponse);
expect($scope.gotoTop).toHaveBeenCalled();
$scope.processing = true;
$scope.saveFailure(mockFailureResponse);
expect($scope.processing).toBe(false);
});